xref: /trunk/main/extensions/source/abpilot/datasourcehandling.cxx (revision 7dbe28d420f41caf4208fa0a77115d7601de2198)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_extensions.hxx"
24 
25 #include "abpresid.hrc"
26 #include "abptypes.hxx"
27 #include "componentmodule.hxx"
28 #include "datasourcehandling.hxx"
29 
30 #include <com/sun/star/beans/XPropertySet.hpp>
31 #include <com/sun/star/container/XNameAccess.hpp>
32 #include <com/sun/star/frame/XStorable.hpp>
33 #include <com/sun/star/lang/XComponent.hpp>
34 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
35 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
36 #include <com/sun/star/sdb/SQLContext.hpp>
37 #include <com/sun/star/sdb/XCompletedConnection.hpp>
38 #include <com/sun/star/sdb/XDatabaseRegistrations.hpp>
39 #include <com/sun/star/sdb/XDocumentDataSource.hpp>
40 #include <com/sun/star/sdbc/XConnection.hpp>
41 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
42 #include <com/sun/star/task/XInteractionHandler.hpp>
43 #include <com/sun/star/uno/XNamingService.hpp>
44 
45 #include <comphelper/interaction.hxx>
46 #include <comphelper/componentcontext.hxx>
47 #include <tools/debug.hxx>
48 #include <tools/diagnose_ex.h>
49 #include <unotools/confignode.hxx>
50 #include <unotools/sharedunocomponent.hxx>
51 #include <vcl/stdtext.hxx>
52 
53 namespace abp
54 {
55 //.........................................................................
56 
57     using namespace ::utl;
58     using namespace ::comphelper;
59     using namespace ::com::sun::star::uno;
60     using namespace ::com::sun::star::lang;
61     using namespace ::com::sun::star::sdb;
62     using namespace ::com::sun::star::sdbc;
63     using namespace ::com::sun::star::task;
64     using namespace ::com::sun::star::beans;
65     using namespace ::com::sun::star::sdbcx;
66     using namespace ::com::sun::star::container;
67     using namespace ::com::sun::star::frame;
68 
69     //=====================================================================
70     struct PackageAccessControl { };
71 
72     //=====================================================================
73     //---------------------------------------------------------------------
lcl_getDataSourceContext(const Reference<XMultiServiceFactory> & _rxORB)74     static Reference< XNameAccess > lcl_getDataSourceContext( const Reference< XMultiServiceFactory >& _rxORB ) SAL_THROW (( Exception ))
75     {
76         Reference< XNameAccess > xContext( _rxORB->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.sdb.DatabaseContext" ) ), UNO_QUERY );
77         DBG_ASSERT(xContext.is(), "lcl_getDataSourceContext: could not access the data source context!");
78         return xContext;
79     }
80 
81     //---------------------------------------------------------------------
82     // creates a new data source and inserts it into the context
lcl_implCreateAndInsert(const Reference<XMultiServiceFactory> & _rxORB,const::rtl::OUString & _rName,Reference<XPropertySet> & _rxNewDataSource)83     static void lcl_implCreateAndInsert(
84         const Reference< XMultiServiceFactory >& _rxORB, const ::rtl::OUString& _rName,
85         Reference< XPropertySet >& /* [out] */ _rxNewDataSource ) SAL_THROW (( ::com::sun::star::uno::Exception ))
86     {
87         //.............................................................
88         // get the data source context
89         Reference< XNameAccess > xContext = lcl_getDataSourceContext( _rxORB );
90 
91         DBG_ASSERT( !xContext->hasByName( _rName ), "lcl_implCreateAndInsert: name already used!" );
92         (void)_rName;
93 
94         //.............................................................
95         // create a new data source
96         Reference< XSingleServiceFactory > xFactory( xContext, UNO_QUERY );
97         Reference< XPropertySet > xNewDataSource;
98         if (xFactory.is())
99             xNewDataSource = Reference< XPropertySet >( xFactory->createInstance(), UNO_QUERY );
100         DBG_ASSERT( xNewDataSource.is(), "lcl_implCreateAndInsert: could not create a new data source!" );
101 
102         //.............................................................
103         // insert the data source into the context
104         Reference< XNamingService > xDynamicContext( xContext, UNO_QUERY );
105         DBG_ASSERT( xDynamicContext.is(), "lcl_implCreateAndInsert: missing an interface on the context (XNamingService)!" );
106         if (xDynamicContext.is())
107         {
108             //  xDynamicContext->registerObject( _rName, xNewDataSource );
109             _rxNewDataSource = xNewDataSource;
110         }
111     }
112 
113     //---------------------------------------------------------------------
114     // creates and inserts a data source, and sets its URL property to the string given
lcl_implCreateAndSetURL(const Reference<XMultiServiceFactory> & _rxORB,const::rtl::OUString & _rName,const sal_Char * _pInitialAsciiURL)115     static ODataSource lcl_implCreateAndSetURL(
116         const Reference< XMultiServiceFactory >& _rxORB, const ::rtl::OUString& _rName,
117         const sal_Char* _pInitialAsciiURL ) SAL_THROW (( ))
118     {
119         ODataSource aReturn( _rxORB );
120         try
121         {
122             // create the new data source
123             Reference< XPropertySet > xNewDataSource;
124             lcl_implCreateAndInsert( _rxORB, _rName, xNewDataSource );
125 
126             //.............................................................
127             // set the URL property
128             if (xNewDataSource.is())
129             {
130                 xNewDataSource->setPropertyValue(
131                     ::rtl::OUString::createFromAscii( "URL" ),
132                     makeAny( ::rtl::OUString::createFromAscii( _pInitialAsciiURL ) )
133                 );
134             }
135 
136             aReturn.setDataSource( xNewDataSource, _rName,PackageAccessControl() );
137         }
138         catch(const Exception&)
139         {
140             DBG_ERROR( "lcl_implCreateAndSetURL: caught an exception while creating the data source!" );
141         }
142 
143         return aReturn;
144     }
145     //---------------------------------------------------------------------
lcl_registerDataSource(const Reference<XMultiServiceFactory> & _rxORB,const::rtl::OUString & _sName,const::rtl::OUString & _sURL)146     void lcl_registerDataSource(
147         const Reference< XMultiServiceFactory >& _rxORB, const ::rtl::OUString& _sName,
148         const ::rtl::OUString& _sURL ) SAL_THROW (( ::com::sun::star::uno::Exception ))
149     {
150         OSL_ENSURE( _sName.getLength(), "lcl_registerDataSource: invalid name!" );
151         OSL_ENSURE( _sURL.getLength(), "lcl_registerDataSource: invalid URL!" );
152         try
153         {
154 
155             ::comphelper::ComponentContext aContext( _rxORB );
156             Reference< XDatabaseRegistrations > xRegistrations(
157                 aContext.createComponent( "com.sun.star.sdb.DatabaseContext" ), UNO_QUERY_THROW );
158 
159             if ( xRegistrations->hasRegisteredDatabase( _sName ) )
160                 xRegistrations->changeDatabaseLocation( _sName, _sURL );
161             else
162                 xRegistrations->registerDatabaseLocation( _sName, _sURL );
163         }
164         catch( const Exception& )
165         {
166             DBG_UNHANDLED_EXCEPTION();
167         }
168     }
169 
170     //=====================================================================
171     //= ODataSourceContextImpl
172     //=====================================================================
173     struct ODataSourceContextImpl
174     {
175         Reference< XMultiServiceFactory >   xORB;
176         Reference< XNameAccess >            xContext;           // the UNO data source context
177         StringBag                           aDataSourceNames;   // for quicker name checks (without the UNO overhead)
178 
ODataSourceContextImplabp::ODataSourceContextImpl179         ODataSourceContextImpl( const Reference< XMultiServiceFactory >& _rxORB ) : xORB( _rxORB ) { }
ODataSourceContextImplabp::ODataSourceContextImpl180         ODataSourceContextImpl( const ODataSourceContextImpl& _rSource )
181             :xORB       ( _rSource.xORB )
182             ,xContext   ( _rSource.xContext )
183         {
184         }
185     };
186 
187     //=====================================================================
188     //= ODataSourceContext
189     //=====================================================================
190     //---------------------------------------------------------------------
ODataSourceContext(const Reference<XMultiServiceFactory> & _rxORB)191     ODataSourceContext::ODataSourceContext(const Reference< XMultiServiceFactory >& _rxORB)
192         :m_pImpl( new ODataSourceContextImpl( _rxORB ) )
193     {
194         try
195         {
196             // create the UNO context
197             m_pImpl->xContext = lcl_getDataSourceContext( _rxORB );
198 
199             if (m_pImpl->xContext.is())
200             {
201                 // collect the data source names
202                 Sequence< ::rtl::OUString > aDSNames = m_pImpl->xContext->getElementNames();
203                 const ::rtl::OUString* pDSNames = aDSNames.getConstArray();
204                 const ::rtl::OUString* pDSNamesEnd = pDSNames + aDSNames.getLength();
205 
206                 for ( ;pDSNames != pDSNamesEnd; ++pDSNames )
207                     m_pImpl->aDataSourceNames.insert( *pDSNames );
208             }
209         }
210         catch( const Exception& )
211         {
212             DBG_ERROR( "ODataSourceContext::ODataSourceContext: caught an exception!" );
213         }
214     }
215 
216     //---------------------------------------------------------------------
disambiguate(::rtl::OUString & _rDataSourceName)217     ::rtl::OUString& ODataSourceContext::disambiguate(::rtl::OUString& _rDataSourceName)
218     {
219         ::rtl::OUString sCheck( _rDataSourceName );
220         ConstStringBagIterator aPos = m_pImpl->aDataSourceNames.find( sCheck );
221 
222         sal_Int32 nPostFix = 1;
223         while ( ( m_pImpl->aDataSourceNames.end() != aPos ) && ( nPostFix < 65535 ) )
224         {   // there already is a data source with this name
225             sCheck = _rDataSourceName;
226             sCheck += ::rtl::OUString::valueOf( nPostFix++ );
227 
228             aPos = m_pImpl->aDataSourceNames.find( sCheck );
229         }
230 
231         _rDataSourceName = sCheck;
232         return _rDataSourceName;
233     }
234 
235     //---------------------------------------------------------------------
getDataSourceNames(StringBag & _rNames) const236     void ODataSourceContext::getDataSourceNames( StringBag& _rNames ) const SAL_THROW (( ))
237     {
238         _rNames = m_pImpl->aDataSourceNames;
239     }
240 
241     //---------------------------------------------------------------------
createNewLDAP(const::rtl::OUString & _rName)242     ODataSource ODataSourceContext::createNewLDAP( const ::rtl::OUString& _rName) SAL_THROW (( ))
243     {
244         return lcl_implCreateAndSetURL( m_pImpl->xORB, _rName, "sdbc:address:ldap:" );
245     }
246 
247     //---------------------------------------------------------------------
createNewThunderbird(const::rtl::OUString & _rName)248     ODataSource ODataSourceContext::createNewThunderbird( const ::rtl::OUString& _rName ) SAL_THROW (( ))
249     {
250         return lcl_implCreateAndSetURL( m_pImpl->xORB, _rName, "sdbc:address:thunderbird" );
251     }
252 
253     //---------------------------------------------------------------------
createNewEvolutionLdap(const::rtl::OUString & _rName)254     ODataSource ODataSourceContext::createNewEvolutionLdap( const ::rtl::OUString& _rName) SAL_THROW (( ))
255     {
256         return lcl_implCreateAndSetURL( m_pImpl->xORB, _rName, "sdbc:address:evolution:ldap" );
257     }
258     //---------------------------------------------------------------------
createNewEvolutionGroupwise(const::rtl::OUString & _rName)259     ODataSource ODataSourceContext::createNewEvolutionGroupwise( const ::rtl::OUString& _rName) SAL_THROW (( ))
260     {
261         return lcl_implCreateAndSetURL( m_pImpl->xORB, _rName, "sdbc:address:evolution:groupwise" );
262     }
263     //---------------------------------------------------------------------
createNewEvolution(const::rtl::OUString & _rName)264     ODataSource ODataSourceContext::createNewEvolution( const ::rtl::OUString& _rName) SAL_THROW (( ))
265     {
266         return lcl_implCreateAndSetURL( m_pImpl->xORB, _rName, "sdbc:address:evolution:local" );
267     }
268 
269     //---------------------------------------------------------------------
createNewKab(const::rtl::OUString & _rName)270     ODataSource ODataSourceContext::createNewKab( const ::rtl::OUString& _rName) SAL_THROW (( ))
271     {
272         return lcl_implCreateAndSetURL( m_pImpl->xORB, _rName, "sdbc:address:kab" );
273     }
274 
275     //---------------------------------------------------------------------
createNewMacab(const::rtl::OUString & _rName)276     ODataSource ODataSourceContext::createNewMacab( const ::rtl::OUString& _rName) SAL_THROW (( ))
277     {
278         return lcl_implCreateAndSetURL( m_pImpl->xORB, _rName, "sdbc:address:macab" );
279     }
280 
281     //---------------------------------------------------------------------
createNewOutlook(const::rtl::OUString & _rName)282     ODataSource ODataSourceContext::createNewOutlook( const ::rtl::OUString& _rName) SAL_THROW (( ))
283     {
284         return lcl_implCreateAndSetURL( m_pImpl->xORB, _rName, "sdbc:address:outlook" );
285     }
286 
287     //---------------------------------------------------------------------
createNewOE(const::rtl::OUString & _rName)288     ODataSource ODataSourceContext::createNewOE( const ::rtl::OUString& _rName) SAL_THROW (( ))
289     {
290         return lcl_implCreateAndSetURL( m_pImpl->xORB, _rName, "sdbc:address:outlookexp" );
291     }
292 
293     //---------------------------------------------------------------------
createNewDBase(const::rtl::OUString & _rName)294     ODataSource ODataSourceContext::createNewDBase( const ::rtl::OUString& _rName) SAL_THROW (( ))
295     {
296         return lcl_implCreateAndSetURL( m_pImpl->xORB, _rName, "sdbc:dbase:" );
297     }
298 
299     //=====================================================================
300     //= ODataSourceImpl
301     //=====================================================================
302     struct ODataSourceImpl
303     {
304     public:
305         Reference< XMultiServiceFactory >       xORB;               // the service factory
306         Reference< XPropertySet >               xDataSource;        // the UNO data source
307         ::utl::SharedUNOComponent< XConnection >
308                                                 xConnection;
309         StringBag                               aTables;            // the cached table names
310         ::rtl::OUString                         sName;
311         sal_Bool                                bTablesUpToDate;    // table name cache up-to-date?
312 
ODataSourceImplabp::ODataSourceImpl313         ODataSourceImpl( const Reference< XMultiServiceFactory >& _rxORB )
314             :xORB( _rxORB )
315             ,bTablesUpToDate( sal_False )
316         {
317         }
318 
319         ODataSourceImpl( const ODataSourceImpl& _rSource );
320     };
321 
322     //---------------------------------------------------------------------
ODataSourceImpl(const ODataSourceImpl & _rSource)323     ODataSourceImpl::ODataSourceImpl( const ODataSourceImpl& _rSource )
324         :xORB( _rSource.xORB )
325         ,xDataSource( _rSource.xDataSource )
326         ,xConnection( _rSource.xConnection )
327         ,aTables( _rSource.aTables )
328         ,sName( _rSource.sName )
329         ,bTablesUpToDate( _rSource.bTablesUpToDate )
330     {
331     }
332 
333     //=====================================================================
334     //= ODataSource
335     //=====================================================================
336     //---------------------------------------------------------------------
ODataSource(const ODataSource & _rSource)337     ODataSource::ODataSource( const ODataSource& _rSource )
338         :m_pImpl( NULL )
339     {
340         *this = _rSource;
341     }
342 
343     //---------------------------------------------------------------------
operator =(const ODataSource & _rSource)344     ODataSource& ODataSource::operator=( const ODataSource& _rSource )
345     {
346         delete m_pImpl;
347         m_pImpl = new ODataSourceImpl( *_rSource.m_pImpl );
348 
349         return *this;
350     }
351 
352     //---------------------------------------------------------------------
ODataSource(const Reference<XMultiServiceFactory> & _rxORB)353     ODataSource::ODataSource( const Reference< XMultiServiceFactory >& _rxORB )
354         :m_pImpl(new ODataSourceImpl(_rxORB))
355     {
356     }
357 
358     //---------------------------------------------------------------------
~ODataSource()359     ODataSource::~ODataSource( )
360     {
361         delete m_pImpl;
362     }
363 
364     //---------------------------------------------------------------------
store()365     void ODataSource::store() SAL_THROW (( ))
366     {
367         if (!isValid())
368             // nothing to do
369             return;
370         try
371         {
372             Reference< XDocumentDataSource > xDocAccess( m_pImpl->xDataSource, UNO_QUERY );
373             Reference< XStorable > xStorable;
374             if ( xDocAccess.is() )
375                 xStorable = xStorable.query( xDocAccess->getDatabaseDocument() );
376             OSL_ENSURE( xStorable.is(),"DataSource is no XStorable!" );
377             if ( xStorable.is() )
378                 xStorable->storeAsURL(m_pImpl->sName,Sequence<PropertyValue>());
379         }
380         catch(const Exception&)
381         {
382             DBG_ERROR( "ODataSource::registerDataSource: caught an exception while creating the data source!" );
383         }
384     }
385     //---------------------------------------------------------------------
registerDataSource(const::rtl::OUString & _sRegisteredDataSourceName)386     void ODataSource::registerDataSource( const ::rtl::OUString& _sRegisteredDataSourceName) SAL_THROW (( ))
387     {
388         if (!isValid())
389             // nothing to do
390             return;
391 
392         try
393         {
394             // invalidate ourself
395             lcl_registerDataSource(m_pImpl->xORB,_sRegisteredDataSourceName,m_pImpl->sName);
396         }
397         catch(const Exception&)
398         {
399             DBG_ERROR( "ODataSource::registerDataSource: caught an exception while creating the data source!" );
400         }
401     }
402 
403     //---------------------------------------------------------------------
setDataSource(const Reference<XPropertySet> & _rxDS,const::rtl::OUString & _sName,PackageAccessControl)404     void ODataSource::setDataSource( const Reference< XPropertySet >& _rxDS,const ::rtl::OUString& _sName, PackageAccessControl )
405     {
406         if (m_pImpl->xDataSource.get() == _rxDS.get())
407             // nothing to do
408             return;
409 
410         if ( isConnected() )
411             disconnect();
412 
413         m_pImpl->sName = _sName;
414         m_pImpl->xDataSource = _rxDS;
415     }
416 
417     //---------------------------------------------------------------------
remove()418     void ODataSource::remove() SAL_THROW (( ))
419     {
420         if (!isValid())
421             // nothing to do
422             return;
423 
424         try
425         {
426             // invalidate ourself
427             m_pImpl->xDataSource.clear();
428         }
429         catch(const Exception&)
430         {
431             DBG_ERROR( "ODataSource::remove: caught an exception while creating the data source!" );
432         }
433     }
434 
435     //---------------------------------------------------------------------
rename(const::rtl::OUString & _rName)436     sal_Bool ODataSource::rename( const ::rtl::OUString& _rName ) SAL_THROW (( ))
437     {
438         if (!isValid())
439             // nothing to do
440             return sal_False;
441 
442         m_pImpl->sName = _rName;
443         return sal_True;
444     }
445 
446     //---------------------------------------------------------------------
getName() const447     ::rtl::OUString ODataSource::getName() const SAL_THROW (( ))
448     {
449         if ( !isValid() )
450             return ::rtl::OUString();
451         return m_pImpl->sName;
452     }
453 
454     //---------------------------------------------------------------------
hasTable(const::rtl::OUString & _rTableName) const455     bool ODataSource::hasTable( const ::rtl::OUString& _rTableName ) const
456     {
457         if ( !isConnected() )
458             return false;
459 
460         const StringBag& aTables( getTableNames() );
461         return aTables.find( _rTableName ) != aTables.end();
462     }
463 
464     //---------------------------------------------------------------------
getTableNames() const465     const StringBag& ODataSource::getTableNames() const SAL_THROW (( ))
466     {
467         m_pImpl->aTables.clear();
468         if ( !isConnected() )
469         {
470             DBG_ERROR( "ODataSource::getTableNames: not connected!" );
471         }
472         else
473         {
474             try
475             {
476                 // get the tables container from the connection
477                 Reference< XTablesSupplier > xSuppTables( m_pImpl->xConnection.getTyped(), UNO_QUERY );
478                 Reference< XNameAccess > xTables;
479                 if ( xSuppTables.is( ) )
480                     xTables = xSuppTables->getTables();
481                 DBG_ASSERT( xTables.is(), "ODataSource::getTableNames: could not retrieve the tables container!" );
482 
483                 // get the names
484                 Sequence< ::rtl::OUString > aTableNames;
485                 if ( xTables.is( ) )
486                     aTableNames = xTables->getElementNames( );
487 
488                 // copy the names
489                 const ::rtl::OUString* pTableNames = aTableNames.getConstArray();
490                 const ::rtl::OUString* pTableNamesEnd = pTableNames + aTableNames.getLength();
491                 for (;pTableNames < pTableNamesEnd; ++pTableNames)
492                     m_pImpl->aTables.insert( *pTableNames );
493             }
494             catch(const Exception&)
495             {
496             }
497         }
498 
499         // now the table cache is up-to-date
500         m_pImpl->bTablesUpToDate = sal_True;
501         return m_pImpl->aTables;
502     }
503 
504     //---------------------------------------------------------------------
connect(Window * _pMessageParent)505     sal_Bool ODataSource::connect( Window* _pMessageParent ) SAL_THROW (( ))
506     {
507         if ( isConnected( ) )
508             // nothing to do
509             return sal_True;
510 
511         // ................................................................
512         // create the interaction handler (needed for authentication and error handling)
513         static ::rtl::OUString s_sInteractionHandlerServiceName = ::rtl::OUString::createFromAscii("com.sun.star.task.InteractionHandler");
514         Reference< XInteractionHandler > xInteractions;
515         try
516         {
517             xInteractions = Reference< XInteractionHandler >(
518                 m_pImpl->xORB->createInstance( s_sInteractionHandlerServiceName ),
519                 UNO_QUERY
520             );
521         }
522         catch(const Exception&)
523         {
524         }
525 
526         // ................................................................
527         // failure to create the interaction handler is a serious issue ...
528         if (!xInteractions.is())
529         {
530             if ( _pMessageParent )
531                 ShowServiceNotAvailableError( _pMessageParent, s_sInteractionHandlerServiceName, sal_True );
532             return sal_False;
533         }
534 
535         // ................................................................
536         // open the connection
537         Any aError;
538         Reference< XConnection > xConnection;
539         try
540         {
541             Reference< XCompletedConnection > xComplConn( m_pImpl->xDataSource, UNO_QUERY );
542             DBG_ASSERT( xComplConn.is(), "ODataSource::connect: missing the XCompletedConnection interface on the data source!" );
543             if ( xComplConn.is() )
544                 xConnection = xComplConn->connectWithCompletion( xInteractions );
545         }
546         catch( const SQLContext& e ) { aError <<= e; }
547         catch( const SQLWarning& e ) { aError <<= e; }
548         catch( const SQLException& e ) { aError <<= e; }
549         catch( const Exception& )
550         {
551             DBG_ERROR( "ODataSource::connect: caught a generic exception!" );
552         }
553 
554         // ................................................................
555         // handle errors
556         if ( aError.hasValue() && _pMessageParent )
557         {
558             try
559             {
560                 SQLException aException;
561                 aError >>= aException;
562                 if ( !aException.Message.getLength() )
563                 {
564                     // prepend some context info
565                     SQLContext aDetailedError;
566                     aDetailedError.Message = String( ModuleRes( RID_STR_NOCONNECTION ) );
567                     aDetailedError.Details = String( ModuleRes( RID_STR_PLEASECHECKSETTINGS ) );
568                     aDetailedError.NextException = aError;
569                     // handle (aka display) the new context info
570                     xInteractions->handle( new OInteractionRequest( makeAny( aDetailedError ) ) );
571                 }
572                 else
573                 {
574                     // handle (aka display) the original error
575                     xInteractions->handle( new OInteractionRequest( makeAny( aException ) ) );
576                 }
577             }
578             catch( const Exception& )
579             {
580                 DBG_ERROR( "ODataSource::connect: caught an exception while trying to display the error!" );
581             }
582         }
583 
584         if ( !xConnection.is() )
585             return sal_False;
586 
587         // ................................................................
588         // success
589         m_pImpl->xConnection.reset( xConnection );
590         m_pImpl->aTables.clear();
591         m_pImpl->bTablesUpToDate = sal_False;
592 
593         return sal_True;
594     }
595 
596     //---------------------------------------------------------------------
disconnect()597     void ODataSource::disconnect( ) SAL_THROW (( ))
598     {
599         m_pImpl->xConnection.clear();
600         m_pImpl->aTables.clear();
601         m_pImpl->bTablesUpToDate = sal_False;
602     }
603 
604     //---------------------------------------------------------------------
isConnected() const605     sal_Bool ODataSource::isConnected( ) const SAL_THROW (( ))
606     {
607         return m_pImpl->xConnection.is();
608     }
609 
610     //---------------------------------------------------------------------
isValid() const611     sal_Bool ODataSource::isValid() const SAL_THROW (( ))
612     {
613         return m_pImpl && m_pImpl->xDataSource.is();
614     }
615     //---------------------------------------------------------------------
getDataSource() const616     Reference< XPropertySet > ODataSource::getDataSource() const SAL_THROW (( ))
617     {
618         return m_pImpl ? m_pImpl->xDataSource : Reference< XPropertySet >();
619     }
620 
621 //.........................................................................
622 }   // namespace abp
623 
624 /* vim: set noet sw=4 ts=4: */
625