1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: HConnection.cxx,v $
10 * $Revision: 1.11.56.3 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_connectivity.hxx"
34 #include "hsqldb/HConnection.hxx"
35 #include "hsqldb/HTools.hxx"
38 #include <connectivity/dbtools.hxx>
40 /** === begin UNO includes === **/
41 #include <com/sun/star/beans/NamedValue.hpp>
42 #include <com/sun/star/container/XNameAccess.hpp>
43 #include <com/sun/star/sdbcx/XDataDefinitionSupplier.hpp>
44 #include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
45 #include <com/sun/star/sdbc/XRow.hpp>
46 #include <com/sun/star/graphic/XGraphicProvider.hpp>
47 #include <com/sun/star/graphic/GraphicColorMode.hpp>
48 #include <com/sun/star/beans/PropertyValue.hpp>
49 #include <com/sun/star/sdbc/XDatabaseMetaData2.hpp>
50 /** === end UNO includes === **/
52 #include <comphelper/componentcontext.hxx>
53 #include <comphelper/listenernotification.hxx>
54 #include <comphelper/sequence.hxx>
55 #include <cppuhelper/exc_hlp.hxx>
56 #include <rtl/ustrbuf.hxx>
57 #include <tools/diagnose_ex.h>
59 #include "resource/sharedresources.hxx"
60 #include "resource/hsqldb_res.hrc"
62 /** === begin UNO using === **/
63 using ::com::sun::star::util::XFlushListener
;
64 using ::com::sun::star::lang::EventObject
;
65 using ::com::sun::star::uno::Reference
;
66 using ::com::sun::star::uno::Exception
;
67 using ::com::sun::star::uno::RuntimeException
;
68 using ::com::sun::star::uno::UNO_QUERY
;
69 using ::com::sun::star::uno::UNO_QUERY_THROW
;
70 using ::com::sun::star::sdbc::XStatement
;
71 using ::com::sun::star::sdbc::XConnection
;
72 using ::com::sun::star::sdbcx::XDataDefinitionSupplier
;
73 using ::com::sun::star::sdbcx::XTablesSupplier
;
74 using ::com::sun::star::container::XNameAccess
;
75 using ::com::sun::star::uno::Sequence
;
76 using ::com::sun::star::beans::NamedValue
;
77 using ::com::sun::star::lang::WrappedTargetException
;
78 using ::com::sun::star::lang::ServiceNotRegisteredException
;
79 using ::com::sun::star::sdbc::XDriver
;
80 using ::com::sun::star::lang::XMultiServiceFactory
;
81 using ::com::sun::star::graphic::XGraphic
;
82 using ::com::sun::star::graphic::XGraphicProvider
;
83 using ::com::sun::star::uno::XInterface
;
84 using ::com::sun::star::lang::IllegalArgumentException
;
85 using ::com::sun::star::ui::dialogs::XExecutableDialog
;
86 using ::com::sun::star::uno::Any
;
87 using ::com::sun::star::uno::makeAny
;
88 using ::com::sun::star::sdbc::XResultSet
;
89 using ::com::sun::star::sdbc::XDatabaseMetaData
;
90 using ::com::sun::star::sdbc::XDatabaseMetaData2
;
91 using ::com::sun::star::sdbc::XRow
;
92 using ::com::sun::star::sdb::application::XDatabaseDocumentUI
;
93 using ::com::sun::star::beans::PropertyValue
;
94 /** === end UNO using === **/
95 namespace GraphicColorMode
= ::com::sun::star::graphic::GraphicColorMode
;
97 namespace connectivity
{ namespace hsqldb
99 // =============================================================================
101 // =============================================================================
102 typedef ::comphelper::OListenerContainerBase
< XFlushListener
, EventObject
> FlushListeners_Base
;
103 class FlushListeners
: public FlushListeners_Base
106 FlushListeners( ::osl::Mutex
& _rMutex
) :FlushListeners_Base( _rMutex
) { }
109 virtual bool implTypedNotify(
110 const Reference
< XFlushListener
>& _rxListener
,
111 const EventObject
& _rEvent
112 ) SAL_THROW( ( Exception
) );
115 // -----------------------------------------------------------------------------
116 bool FlushListeners::implTypedNotify( const Reference
< XFlushListener
>& _rxListener
, const EventObject
& _rEvent
) SAL_THROW( ( Exception
) )
118 _rxListener
->flushed( _rEvent
);
119 return true; // continue notifying the other listeners, if any
122 // =============================================================================
124 // =============================================================================
125 // -----------------------------------------------------------------------------
126 void SAL_CALL
OHsqlConnection::disposing(void)
128 m_aFlushListeners
.disposeAndClear( EventObject( *this ) );
129 OHsqlConnection_BASE::disposing();
130 OConnectionWrapper::disposing();
132 // -----------------------------------------------------------------------------
133 OHsqlConnection::OHsqlConnection( const Reference
< XDriver
> _rxDriver
,
134 const Reference
< XConnection
>& _xConnection
,const Reference
< XMultiServiceFactory
>& _xORB
)
135 :OHsqlConnection_BASE( m_aMutex
)
136 ,m_aFlushListeners( m_aMutex
)
137 ,m_xDriver( _rxDriver
)
142 setDelegation(_xConnection
,_xORB
,m_refCount
);
144 // -----------------------------------------------------------------------------
145 OHsqlConnection::~OHsqlConnection()
147 if ( !OHsqlConnection_BASE::rBHelper
.bDisposed
)
149 osl_incrementInterlockedCount( &m_refCount
);
153 // -----------------------------------------------------------------------------
154 IMPLEMENT_FORWARD_XINTERFACE2(OHsqlConnection
,OHsqlConnection_BASE
,OConnectionWrapper
)
155 IMPLEMENT_SERVICE_INFO(OHsqlConnection
, "com.sun.star.sdbc.drivers.hsqldb.OHsqlConnection", "com.sun.star.sdbc.Connection")
156 IMPLEMENT_FORWARD_XTYPEPROVIDER2(OHsqlConnection
,OHsqlConnection_BASE
,OConnectionWrapper
)
158 //--------------------------------------------------------------------
159 ::osl::Mutex
& OHsqlConnection::getMutex() const
164 //--------------------------------------------------------------------
165 void OHsqlConnection::checkDisposed() const
167 ::connectivity::checkDisposed( rBHelper
.bDisposed
);
171 //--------------------------------------------------------------------
172 void SAL_CALL
OHsqlConnection::flush( ) throw (RuntimeException
)
174 MethodGuard
aGuard( *this );
178 if ( m_xConnection
.is() )
183 Reference
< XDatabaseMetaData2
> xMeta2(m_xConnection
->getMetaData(),UNO_QUERY_THROW
);
184 const Sequence
< PropertyValue
> aInfo
= xMeta2
->getConnectionInfo();
185 const PropertyValue
* pIter
= aInfo
.getConstArray();
186 const PropertyValue
* pEnd
= pIter
+ aInfo
.getLength();
187 for(;pIter
!= pEnd
;++pIter
)
189 if ( pIter
->Name
.compareToAscii("readonly") == 0 )
195 Reference
< XStatement
> xStmt( m_xConnection
->createStatement(), UNO_QUERY_THROW
);
196 xStmt
->execute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CHECKPOINT" ) ) );
200 EventObject
aFlushedEvent( *this );
201 m_aFlushListeners
.notifyEach( &XFlushListener::flushed
, aFlushedEvent
);
203 catch(const Exception
& )
205 DBG_UNHANDLED_EXCEPTION();
209 //--------------------------------------------------------------------
210 void SAL_CALL
OHsqlConnection::addFlushListener( const Reference
< XFlushListener
>& l
) throw (RuntimeException
)
212 MethodGuard
aGuard( *this );
213 m_aFlushListeners
.addInterface( l
);
216 //--------------------------------------------------------------------
217 void SAL_CALL
OHsqlConnection::removeFlushListener( const Reference
< XFlushListener
>& l
) throw (RuntimeException
)
219 MethodGuard
aGuard( *this );
220 m_aFlushListeners
.removeInterface( l
);
223 // -------------------------------------------------------------------
224 Reference
< XGraphic
> SAL_CALL
OHsqlConnection::getTableIcon( const ::rtl::OUString
& _TableName
, ::sal_Int32 _ColorMode
) throw (RuntimeException
)
226 MethodGuard
aGuard( *this );
228 impl_checkExistingTable_throw( _TableName
);
229 if ( !impl_isTextTable_nothrow( _TableName
) )
232 return impl_getTextTableIcon_nothrow( _ColorMode
);
235 // -------------------------------------------------------------------
236 Reference
< XInterface
> SAL_CALL
OHsqlConnection::getTableEditor( const Reference
< XDatabaseDocumentUI
>& _DocumentUI
, const ::rtl::OUString
& _TableName
) throw (IllegalArgumentException
, WrappedTargetException
, RuntimeException
)
238 MethodGuard
aGuard( *this );
240 impl_checkExistingTable_throw( _TableName
);
241 if ( !impl_isTextTable_nothrow( _TableName
) )
244 if ( !_DocumentUI
.is() )
246 ::connectivity::SharedResources aResources
;
247 const ::rtl::OUString
sError( aResources
.getResourceString(STR_NO_DOCUMENTUI
));
248 throw IllegalArgumentException(
253 } // if ( !_DocumentUI.is() )
256 // Reference< XExecutableDialog > xEditor = impl_createLinkedTableEditor_throw( _DocumentUI, _TableName );
257 // return xEditor.get();
259 // editor not yet implemented in this CWS
262 // -------------------------------------------------------------------
263 Reference
< XNameAccess
> OHsqlConnection::impl_getTableContainer_throw()
265 Reference
< XNameAccess
> xTables
;
268 Reference
< XConnection
> xMe( *this, UNO_QUERY
);
269 Reference
< XDataDefinitionSupplier
> xDefinitionsSupp( m_xDriver
, UNO_QUERY_THROW
);
270 Reference
< XTablesSupplier
> xTablesSupp( xDefinitionsSupp
->getDataDefinitionByConnection( xMe
), UNO_QUERY_THROW
);
271 xTables
.set( xTablesSupp
->getTables(), UNO_QUERY_THROW
);
273 catch( const RuntimeException
& ) { throw; }
274 catch( const Exception
& )
276 ::connectivity::SharedResources aResources
;
277 const ::rtl::OUString
sError( aResources
.getResourceString(STR_NO_TABLE_CONTAINER
));
278 throw WrappedTargetException( sError
,*this, ::cppu::getCaughtException() );
281 OSL_POSTCOND( xTables
.is(), "OHsqlConnection::impl_getTableContainer_throw: post condition not met!" );
287 // -------------------------------------------------------------------
288 Reference
< XExecutableDialog
> OHsqlConnection::impl_createLinkedTableEditor_throw( const Reference
< XDatabaseDocumentUI
>& _rxDocumentUI
, const ::rtl::OUString
& _rTableName
)
290 OSL_PRECOND( _rxDocumentUI
.is(), "OHsqlConnection::impl_createLinkedTableEditor_throw: illegal document UI!" );
291 Reference
< XExecutableDialog
> xDialog
;
294 ::comphelper::ComponentContext
aContext( m_xORB
);
295 Sequence
< Any
> aArguments(3);
296 aArguments
[0] <<= NamedValue(
297 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TableContainer" ) ),
298 makeAny( impl_getTableContainer_throw() )
300 aArguments
[1] <<= NamedValue(
301 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TableName" ) ),
302 makeAny( _rTableName
)
304 aArguments
[2] <<= NamedValue(
305 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ParentWindow" ) ),
306 makeAny( _rxDocumentUI
->getApplicationMainWindow() )
309 aContext
.createComponentWithArguments( "com.sun.star.sdb.hsql.LinkedTableEditor", aArguments
, xDialog
);
311 throw ServiceNotRegisteredException( ::rtl::OUString::createFromAscii( "com.sun.star.sdb.hsql.LinkedTableEditor" ), *this );
313 catch( const RuntimeException
& ) { throw; }
314 catch( const Exception
& )
316 ::connectivity::SharedResources aResources
;
317 const ::rtl::OUString
sError( aResources
.getResourceString(STR_NO_TABLE_EDITOR_DIALOG
));
318 throw WrappedTargetException( sError
,*this, ::cppu::getCaughtException() );
324 // -------------------------------------------------------------------
325 void OHsqlConnection::impl_checkExistingTable_throw( const ::rtl::OUString
& _rTableName
)
327 bool bDoesExist
= false;
330 Reference
< XNameAccess
> xTables( impl_getTableContainer_throw(), UNO_QUERY_THROW
);
332 bDoesExist
= xTables
->hasByName( _rTableName
);
334 catch( const Exception
& )
336 // that's a serious error in impl_getTableContainer_throw, or hasByName, however, we're only
337 // allowed to throw an IllegalArgumentException ourself
338 DBG_UNHANDLED_EXCEPTION();
343 ::connectivity::SharedResources aResources
;
344 const ::rtl::OUString
sError( aResources
.getResourceStringWithSubstitution(
346 "$tablename$", _rTableName
348 throw IllegalArgumentException( sError
,*this, 0 );
349 } // if ( !bDoesExist )
352 // -------------------------------------------------------------------
353 bool OHsqlConnection::impl_isTextTable_nothrow( const ::rtl::OUString
& _rTableName
)
355 bool bIsTextTable
= false;
358 Reference
< XConnection
> xMe( *this, UNO_QUERY_THROW
);
360 // split the fully qualified name
361 Reference
< XDatabaseMetaData
> xMetaData( xMe
->getMetaData(), UNO_QUERY_THROW
);
362 ::rtl::OUString sCatalog
, sSchema
, sName
;
363 ::dbtools::qualifiedNameComponents( xMetaData
, _rTableName
, sCatalog
, sSchema
, sName
, ::dbtools::eComplete
);
365 // get the table information
366 ::rtl::OUStringBuffer sSQL
;
367 sSQL
.appendAscii( "SELECT HSQLDB_TYPE FROM INFORMATION_SCHEMA.SYSTEM_TABLES" );
368 HTools::appendTableFilterCrit( sSQL
, sCatalog
, sSchema
, sName
, true );
369 sSQL
.appendAscii( " AND TABLE_TYPE = 'TABLE'" );
371 Reference
< XStatement
> xStatement( xMe
->createStatement(), UNO_QUERY_THROW
);
372 Reference
< XResultSet
> xTableHsqlType( xStatement
->executeQuery( sSQL
.makeStringAndClear() ), UNO_QUERY_THROW
);
374 if ( xTableHsqlType
->next() ) // might not succeed in case of VIEWs
376 Reference
< XRow
> xValueAccess( xTableHsqlType
, UNO_QUERY_THROW
);
377 ::rtl::OUString sTableType
= xValueAccess
->getString( 1 );
378 bIsTextTable
= sTableType
.equalsAscii( "TEXT" );
381 catch( const Exception
& )
383 DBG_UNHANDLED_EXCEPTION();
389 // -------------------------------------------------------------------
390 Reference
< XGraphic
> OHsqlConnection::impl_getTextTableIcon_nothrow( ::sal_Int32 _ColorMode
)
392 Reference
< XGraphic
> xGraphic
;
395 // create a graphic provider
396 Reference
< XGraphicProvider
> xProvider
;
398 xProvider
.set( m_xORB
->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.graphic.GraphicProvider" ) ) ), UNO_QUERY_THROW
);
400 // assemble the image URL
401 ::rtl::OUStringBuffer aImageURL
;
402 aImageURL
.appendAscii( "private:graphicrepository/" ); // load the graphic from the global graphic repository
403 aImageURL
.appendAscii( "database/" ); // the relative path within the images.zip
404 if ( _ColorMode
== GraphicColorMode::NORMAL
)
405 aImageURL
.appendAscii( LINKED_TEXT_TABLE_IMAGE_RESOURCE
);
407 aImageURL
.appendAscii( LINKED_TEXT_TABLE_IMAGE_RESOURCE_HC
);
408 // the name of the graphic to use
409 ::rtl::OUString
sImageURL( aImageURL
.makeStringAndClear() );
411 // ask the provider to obtain a graphic
412 Sequence
< PropertyValue
> aMediaProperties( 1 );
413 aMediaProperties
[0].Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
414 aMediaProperties
[0].Value
<<= sImageURL
;
415 xGraphic
= xProvider
->queryGraphic( aMediaProperties
);
416 OSL_ENSURE( xGraphic
.is(), "OHsqlConnection::impl_getTextTableIcon_nothrow: the provider did not give us a graphic object!" );
418 catch( const Exception
& )
420 DBG_UNHANDLED_EXCEPTION();
425 } } // namespace connectivity::hsqldb