1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_connectivity.hxx" 30 31 #include "hsqldb/HConnection.hxx" 32 #include "hsqldb/HTools.hxx" 33 #include "hsqlui.hrc" 34 35 #include <connectivity/dbtools.hxx> 36 37 /** === begin UNO includes === **/ 38 #include <com/sun/star/beans/NamedValue.hpp> 39 #include <com/sun/star/container/XNameAccess.hpp> 40 #include <com/sun/star/sdbcx/XDataDefinitionSupplier.hpp> 41 #include <com/sun/star/lang/ServiceNotRegisteredException.hpp> 42 #include <com/sun/star/sdbc/XRow.hpp> 43 #include <com/sun/star/graphic/XGraphicProvider.hpp> 44 #include <com/sun/star/graphic/GraphicColorMode.hpp> 45 #include <com/sun/star/beans/PropertyValue.hpp> 46 #include <com/sun/star/sdbc/XDatabaseMetaData2.hpp> 47 /** === end UNO includes === **/ 48 49 #include <comphelper/componentcontext.hxx> 50 #include <comphelper/listenernotification.hxx> 51 #include <comphelper/sequence.hxx> 52 #include <cppuhelper/exc_hlp.hxx> 53 #include <rtl/ustrbuf.hxx> 54 #include <tools/diagnose_ex.h> 55 56 #include "resource/sharedresources.hxx" 57 #include "resource/hsqldb_res.hrc" 58 59 /** === begin UNO using === **/ 60 using ::com::sun::star::util::XFlushListener; 61 using ::com::sun::star::lang::EventObject; 62 using ::com::sun::star::uno::Reference; 63 using ::com::sun::star::uno::Exception; 64 using ::com::sun::star::uno::RuntimeException; 65 using ::com::sun::star::uno::UNO_QUERY; 66 using ::com::sun::star::uno::UNO_QUERY_THROW; 67 using ::com::sun::star::sdbc::XStatement; 68 using ::com::sun::star::sdbc::XConnection; 69 using ::com::sun::star::sdbcx::XDataDefinitionSupplier; 70 using ::com::sun::star::sdbcx::XTablesSupplier; 71 using ::com::sun::star::container::XNameAccess; 72 using ::com::sun::star::uno::Sequence; 73 using ::com::sun::star::beans::NamedValue; 74 using ::com::sun::star::lang::WrappedTargetException; 75 using ::com::sun::star::lang::ServiceNotRegisteredException; 76 using ::com::sun::star::sdbc::XDriver; 77 using ::com::sun::star::lang::XMultiServiceFactory; 78 using ::com::sun::star::graphic::XGraphic; 79 using ::com::sun::star::graphic::XGraphicProvider; 80 using ::com::sun::star::uno::XInterface; 81 using ::com::sun::star::lang::IllegalArgumentException; 82 using ::com::sun::star::ui::dialogs::XExecutableDialog; 83 using ::com::sun::star::uno::Any; 84 using ::com::sun::star::uno::makeAny; 85 using ::com::sun::star::sdbc::XResultSet; 86 using ::com::sun::star::sdbc::XDatabaseMetaData; 87 using ::com::sun::star::sdbc::XDatabaseMetaData2; 88 using ::com::sun::star::sdbc::XRow; 89 using ::com::sun::star::sdb::application::XDatabaseDocumentUI; 90 using ::com::sun::star::beans::PropertyValue; 91 /** === end UNO using === **/ 92 namespace GraphicColorMode = ::com::sun::star::graphic::GraphicColorMode; 93 94 namespace connectivity { namespace hsqldb 95 { 96 // ============================================================================= 97 // = FlushListeners 98 // ============================================================================= 99 typedef ::comphelper::OListenerContainerBase< XFlushListener, EventObject > FlushListeners_Base; 100 class FlushListeners : public FlushListeners_Base 101 { 102 public: 103 FlushListeners( ::osl::Mutex& _rMutex ) :FlushListeners_Base( _rMutex ) { } 104 105 protected: 106 virtual bool implTypedNotify( 107 const Reference< XFlushListener >& _rxListener, 108 const EventObject& _rEvent 109 ) SAL_THROW( ( Exception ) ); 110 }; 111 112 // ----------------------------------------------------------------------------- 113 bool FlushListeners::implTypedNotify( const Reference< XFlushListener >& _rxListener, const EventObject& _rEvent ) SAL_THROW( ( Exception ) ) 114 { 115 _rxListener->flushed( _rEvent ); 116 return true; // continue notifying the other listeners, if any 117 } 118 119 // ============================================================================= 120 // = OHsqlConnection 121 // ============================================================================= 122 // ----------------------------------------------------------------------------- 123 void SAL_CALL OHsqlConnection::disposing(void) 124 { 125 m_aFlushListeners.disposeAndClear( EventObject( *this ) ); 126 OHsqlConnection_BASE::disposing(); 127 OConnectionWrapper::disposing(); 128 } 129 // ----------------------------------------------------------------------------- 130 OHsqlConnection::OHsqlConnection( const Reference< XDriver > _rxDriver, 131 const Reference< XConnection >& _xConnection ,const Reference< XMultiServiceFactory>& _xORB ) 132 :OHsqlConnection_BASE( m_aMutex ) 133 ,m_aFlushListeners( m_aMutex ) 134 ,m_xDriver( _rxDriver ) 135 ,m_xORB( _xORB ) 136 ,m_bIni(true) 137 ,m_bReadOnly(false) 138 { 139 setDelegation(_xConnection,_xORB,m_refCount); 140 } 141 // ----------------------------------------------------------------------------- 142 OHsqlConnection::~OHsqlConnection() 143 { 144 if ( !OHsqlConnection_BASE::rBHelper.bDisposed ) 145 { 146 osl_incrementInterlockedCount( &m_refCount ); 147 dispose(); 148 } 149 } 150 // ----------------------------------------------------------------------------- 151 IMPLEMENT_FORWARD_XINTERFACE2(OHsqlConnection,OHsqlConnection_BASE,OConnectionWrapper) 152 IMPLEMENT_SERVICE_INFO(OHsqlConnection, "com.sun.star.sdbc.drivers.hsqldb.OHsqlConnection", "com.sun.star.sdbc.Connection") 153 IMPLEMENT_FORWARD_XTYPEPROVIDER2(OHsqlConnection,OHsqlConnection_BASE,OConnectionWrapper) 154 155 //-------------------------------------------------------------------- 156 ::osl::Mutex& OHsqlConnection::getMutex() const 157 { 158 return m_aMutex; 159 } 160 161 //-------------------------------------------------------------------- 162 void OHsqlConnection::checkDisposed() const 163 { 164 ::connectivity::checkDisposed( rBHelper.bDisposed ); 165 } 166 167 // XFlushable 168 //-------------------------------------------------------------------- 169 void SAL_CALL OHsqlConnection::flush( ) throw (RuntimeException) 170 { 171 MethodGuard aGuard( *this ); 172 173 try 174 { 175 if ( m_xConnection.is() ) 176 { 177 if ( m_bIni ) 178 { 179 m_bIni = false; 180 Reference< XDatabaseMetaData2 > xMeta2(m_xConnection->getMetaData(),UNO_QUERY_THROW); 181 const Sequence< PropertyValue > aInfo = xMeta2->getConnectionInfo(); 182 const PropertyValue* pIter = aInfo.getConstArray(); 183 const PropertyValue* pEnd = pIter + aInfo.getLength(); 184 for(;pIter != pEnd;++pIter) 185 { 186 if ( pIter->Name.compareToAscii("readonly") == 0 ) 187 m_bReadOnly = true; 188 } 189 } 190 if ( !m_bReadOnly ) 191 { 192 Reference< XStatement > xStmt( m_xConnection->createStatement(), UNO_QUERY_THROW ); 193 xStmt->execute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CHECKPOINT" ) ) ); 194 } 195 } 196 197 EventObject aFlushedEvent( *this ); 198 m_aFlushListeners.notifyEach( &XFlushListener::flushed, aFlushedEvent ); 199 } 200 catch(const Exception& ) 201 { 202 DBG_UNHANDLED_EXCEPTION(); 203 } 204 } 205 206 //-------------------------------------------------------------------- 207 void SAL_CALL OHsqlConnection::addFlushListener( const Reference< XFlushListener >& l ) throw (RuntimeException) 208 { 209 MethodGuard aGuard( *this ); 210 m_aFlushListeners.addInterface( l ); 211 } 212 213 //-------------------------------------------------------------------- 214 void SAL_CALL OHsqlConnection::removeFlushListener( const Reference< XFlushListener >& l ) throw (RuntimeException) 215 { 216 MethodGuard aGuard( *this ); 217 m_aFlushListeners.removeInterface( l ); 218 } 219 220 // ------------------------------------------------------------------- 221 Reference< XGraphic > SAL_CALL OHsqlConnection::getTableIcon( const ::rtl::OUString& _TableName, ::sal_Int32 _ColorMode ) throw (RuntimeException) 222 { 223 MethodGuard aGuard( *this ); 224 225 impl_checkExistingTable_throw( _TableName ); 226 if ( !impl_isTextTable_nothrow( _TableName ) ) 227 return NULL; 228 229 return impl_getTextTableIcon_nothrow( _ColorMode ); 230 } 231 232 // ------------------------------------------------------------------- 233 Reference< XInterface > SAL_CALL OHsqlConnection::getTableEditor( const Reference< XDatabaseDocumentUI >& _DocumentUI, const ::rtl::OUString& _TableName ) throw (IllegalArgumentException, WrappedTargetException, RuntimeException) 234 { 235 MethodGuard aGuard( *this ); 236 237 impl_checkExistingTable_throw( _TableName ); 238 if ( !impl_isTextTable_nothrow( _TableName ) ) 239 return NULL; 240 241 if ( !_DocumentUI.is() ) 242 { 243 ::connectivity::SharedResources aResources; 244 const ::rtl::OUString sError( aResources.getResourceString(STR_NO_DOCUMENTUI)); 245 throw IllegalArgumentException( 246 sError, 247 *this, 248 0 249 ); 250 } // if ( !_DocumentUI.is() ) 251 252 253 // Reference< XExecutableDialog > xEditor = impl_createLinkedTableEditor_throw( _DocumentUI, _TableName ); 254 // return xEditor.get(); 255 return NULL; 256 // editor not yet implemented in this CWS 257 } 258 259 // ------------------------------------------------------------------- 260 Reference< XNameAccess > OHsqlConnection::impl_getTableContainer_throw() 261 { 262 Reference< XNameAccess > xTables; 263 try 264 { 265 Reference< XConnection > xMe( *this, UNO_QUERY ); 266 Reference< XDataDefinitionSupplier > xDefinitionsSupp( m_xDriver, UNO_QUERY_THROW ); 267 Reference< XTablesSupplier > xTablesSupp( xDefinitionsSupp->getDataDefinitionByConnection( xMe ), UNO_QUERY_THROW ); 268 xTables.set( xTablesSupp->getTables(), UNO_QUERY_THROW ); 269 } 270 catch( const RuntimeException& ) { throw; } 271 catch( const Exception& ) 272 { 273 ::connectivity::SharedResources aResources; 274 const ::rtl::OUString sError( aResources.getResourceString(STR_NO_TABLE_CONTAINER)); 275 throw WrappedTargetException( sError ,*this, ::cppu::getCaughtException() ); 276 } 277 278 OSL_POSTCOND( xTables.is(), "OHsqlConnection::impl_getTableContainer_throw: post condition not met!" ); 279 return xTables; 280 } 281 282 //TODO: resource 283 #if 0 284 // ------------------------------------------------------------------- 285 Reference< XExecutableDialog > OHsqlConnection::impl_createLinkedTableEditor_throw( const Reference< XDatabaseDocumentUI >& _rxDocumentUI, const ::rtl::OUString& _rTableName ) 286 { 287 OSL_PRECOND( _rxDocumentUI.is(), "OHsqlConnection::impl_createLinkedTableEditor_throw: illegal document UI!" ); 288 Reference< XExecutableDialog > xDialog; 289 try 290 { 291 ::comphelper::ComponentContext aContext( m_xORB ); 292 Sequence< Any > aArguments(3); 293 aArguments[0] <<= NamedValue( 294 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TableContainer" ) ), 295 makeAny( impl_getTableContainer_throw() ) 296 ); 297 aArguments[1] <<= NamedValue( 298 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TableName" ) ), 299 makeAny( _rTableName ) 300 ); 301 aArguments[2] <<= NamedValue( 302 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ParentWindow" ) ), 303 makeAny( _rxDocumentUI->getApplicationMainWindow() ) 304 ); 305 306 aContext.createComponentWithArguments( "com.sun.star.sdb.hsql.LinkedTableEditor", aArguments, xDialog ); 307 if ( !xDialog.is() ) 308 throw ServiceNotRegisteredException( ::rtl::OUString::createFromAscii( "com.sun.star.sdb.hsql.LinkedTableEditor" ), *this ); 309 } 310 catch( const RuntimeException& ) { throw; } 311 catch( const Exception& ) 312 { 313 ::connectivity::SharedResources aResources; 314 const ::rtl::OUString sError( aResources.getResourceString(STR_NO_TABLE_EDITOR_DIALOG)); 315 throw WrappedTargetException( sError ,*this, ::cppu::getCaughtException() ); 316 } 317 return xDialog; 318 } 319 #endif 320 321 // ------------------------------------------------------------------- 322 void OHsqlConnection::impl_checkExistingTable_throw( const ::rtl::OUString& _rTableName ) 323 { 324 bool bDoesExist = false; 325 try 326 { 327 Reference< XNameAccess > xTables( impl_getTableContainer_throw(), UNO_QUERY_THROW ); 328 if ( xTables.is() ) 329 bDoesExist = xTables->hasByName( _rTableName ); 330 } 331 catch( const Exception& ) 332 { 333 // that's a serious error in impl_getTableContainer_throw, or hasByName, however, we're only 334 // allowed to throw an IllegalArgumentException ourself 335 DBG_UNHANDLED_EXCEPTION(); 336 } 337 338 if ( !bDoesExist ) 339 { 340 ::connectivity::SharedResources aResources; 341 const ::rtl::OUString sError( aResources.getResourceStringWithSubstitution( 342 STR_NO_TABLENAME, 343 "$tablename$", _rTableName 344 )); 345 throw IllegalArgumentException( sError,*this, 0 ); 346 } // if ( !bDoesExist ) 347 } 348 349 // ------------------------------------------------------------------- 350 bool OHsqlConnection::impl_isTextTable_nothrow( const ::rtl::OUString& _rTableName ) 351 { 352 bool bIsTextTable = false; 353 try 354 { 355 Reference< XConnection > xMe( *this, UNO_QUERY_THROW ); 356 357 // split the fully qualified name 358 Reference< XDatabaseMetaData > xMetaData( xMe->getMetaData(), UNO_QUERY_THROW ); 359 ::rtl::OUString sCatalog, sSchema, sName; 360 ::dbtools::qualifiedNameComponents( xMetaData, _rTableName, sCatalog, sSchema, sName, ::dbtools::eComplete ); 361 362 // get the table information 363 ::rtl::OUStringBuffer sSQL; 364 sSQL.appendAscii( "SELECT HSQLDB_TYPE FROM INFORMATION_SCHEMA.SYSTEM_TABLES" ); 365 HTools::appendTableFilterCrit( sSQL, sCatalog, sSchema, sName, true ); 366 sSQL.appendAscii( " AND TABLE_TYPE = 'TABLE'" ); 367 368 Reference< XStatement > xStatement( xMe->createStatement(), UNO_QUERY_THROW ); 369 Reference< XResultSet > xTableHsqlType( xStatement->executeQuery( sSQL.makeStringAndClear() ), UNO_QUERY_THROW ); 370 371 if ( xTableHsqlType->next() ) // might not succeed in case of VIEWs 372 { 373 Reference< XRow > xValueAccess( xTableHsqlType, UNO_QUERY_THROW ); 374 ::rtl::OUString sTableType = xValueAccess->getString( 1 ); 375 bIsTextTable = sTableType.equalsAscii( "TEXT" ); 376 } 377 } 378 catch( const Exception& ) 379 { 380 DBG_UNHANDLED_EXCEPTION(); 381 } 382 383 return bIsTextTable; 384 } 385 386 // ------------------------------------------------------------------- 387 Reference< XGraphic > OHsqlConnection::impl_getTextTableIcon_nothrow( ::sal_Int32 _ColorMode ) 388 { 389 Reference< XGraphic > xGraphic; 390 try 391 { 392 // create a graphic provider 393 Reference< XGraphicProvider > xProvider; 394 if ( m_xORB.is() ) 395 xProvider.set( m_xORB->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.graphic.GraphicProvider" ) ) ), UNO_QUERY_THROW ); 396 397 // assemble the image URL 398 ::rtl::OUStringBuffer aImageURL; 399 aImageURL.appendAscii( "private:graphicrepository/" ); // load the graphic from the global graphic repository 400 aImageURL.appendAscii( "database/" ); // the relative path within the images.zip 401 if ( _ColorMode == GraphicColorMode::NORMAL ) 402 aImageURL.appendAscii( LINKED_TEXT_TABLE_IMAGE_RESOURCE ); 403 else 404 aImageURL.appendAscii( LINKED_TEXT_TABLE_IMAGE_RESOURCE_HC ); 405 // the name of the graphic to use 406 ::rtl::OUString sImageURL( aImageURL.makeStringAndClear() ); 407 408 // ask the provider to obtain a graphic 409 Sequence< PropertyValue > aMediaProperties( 1 ); 410 aMediaProperties[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ); 411 aMediaProperties[0].Value <<= sImageURL; 412 xGraphic = xProvider->queryGraphic( aMediaProperties ); 413 OSL_ENSURE( xGraphic.is(), "OHsqlConnection::impl_getTextTableIcon_nothrow: the provider did not give us a graphic object!" ); 414 } 415 catch( const Exception& ) 416 { 417 DBG_UNHANDLED_EXCEPTION(); 418 } 419 return xGraphic; 420 } 421 422 } } // namespace connectivity::hsqldb 423