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