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_dbaccess.hxx" 30 31 #include "dbu_reghelper.hxx" 32 #include "dbustrings.hrc" 33 #include "UITools.hxx" 34 35 /** === begin UNO includes === **/ 36 #include <com/sun/star/container/XChild.hpp> 37 #include <com/sun/star/container/XNameAccess.hpp> 38 #include <com/sun/star/container/XSet.hpp> 39 #include <com/sun/star/document/XEventListener.hpp> 40 #include <com/sun/star/frame/XController2.hpp> 41 #include <com/sun/star/frame/XFrame.hpp> 42 #include <com/sun/star/frame/XFrameLoader.hpp> 43 #include <com/sun/star/frame/XLoadEventListener.hpp> 44 #include <com/sun/star/lang/XInitialization.hpp> 45 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 46 #include <com/sun/star/lang/XServiceInfo.hpp> 47 #include <com/sun/star/lang/XSingleServiceFactory.hpp> 48 #include <com/sun/star/registry/XRegistryKey.hpp> 49 #include <com/sun/star/sdbc/XConnection.hpp> 50 #include <com/sun/star/frame/XModule.hpp> 51 /** === end UNO includes === **/ 52 53 #include <com/sun/star/sdbc/XDataSource.hpp> 54 #include <comphelper/namedvaluecollection.hxx> 55 #include <comphelper/componentcontext.hxx> 56 #include <cppuhelper/implbase2.hxx> 57 #include <toolkit/awt/vclxwindow.hxx> 58 #include <toolkit/helper/vclunohelper.hxx> 59 #include <tools/diagnose_ex.h> 60 #include <tools/urlobj.hxx> 61 #include <vcl/svapp.hxx> 62 63 using namespace ::com::sun::star; 64 using namespace ::com::sun::star::uno; 65 using namespace ::com::sun::star::frame; 66 using namespace ::com::sun::star::beans; 67 using namespace ::com::sun::star::sdbc; 68 using namespace ::com::sun::star::container; 69 using namespace ::com::sun::star::lang; 70 using namespace ::com::sun::star::registry; 71 using ::com::sun::star::sdbc::XDataSource; 72 using namespace dbaui; 73 74 class DBContentLoader : public ::cppu::WeakImplHelper2< XFrameLoader, XServiceInfo> 75 { 76 private: 77 ::rtl::OUString m_aURL; 78 Sequence< PropertyValue> m_aArgs; 79 Reference< XLoadEventListener > m_xListener; 80 Reference< XFrame > m_xFrame; 81 Reference< XMultiServiceFactory > m_xServiceFactory; 82 public: 83 DBContentLoader(const Reference< XMultiServiceFactory >&); 84 ~DBContentLoader(); 85 86 // XServiceInfo 87 ::rtl::OUString SAL_CALL getImplementationName() throw( ); 88 sal_Bool SAL_CALL supportsService(const ::rtl::OUString& ServiceName) throw( ); 89 Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(void) throw( ); 90 91 // static methods 92 static ::rtl::OUString getImplementationName_Static() throw( ) 93 { 94 return ::rtl::OUString::createFromAscii("org.openoffice.comp.dbu.DBContentLoader"); 95 } 96 static Sequence< ::rtl::OUString> getSupportedServiceNames_Static(void) throw( ); 97 static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > 98 SAL_CALL Create(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&); 99 100 // XLoader 101 virtual void SAL_CALL load( const Reference< XFrame > & _rFrame, const ::rtl::OUString& _rURL, 102 const Sequence< PropertyValue >& _rArgs, 103 const Reference< XLoadEventListener > & _rListener) throw(::com::sun::star::uno::RuntimeException); 104 virtual void SAL_CALL cancel(void) throw(); 105 }; 106 DBG_NAME(DBContentLoader) 107 108 DBContentLoader::DBContentLoader(const Reference< XMultiServiceFactory >& _rxFactory) 109 :m_xServiceFactory(_rxFactory) 110 { 111 DBG_CTOR(DBContentLoader,NULL); 112 113 } 114 // ------------------------------------------------------------------------- 115 116 DBContentLoader::~DBContentLoader() 117 { 118 119 DBG_DTOR(DBContentLoader,NULL); 120 } 121 // ------------------------------------------------------------------------- 122 // ------------------------------------------------------------------------- 123 extern "C" void SAL_CALL createRegistryInfo_DBContentLoader() 124 { 125 static ::dbaui::OMultiInstanceAutoRegistration< DBContentLoader > aAutoRegistration; 126 } 127 // ------------------------------------------------------------------------- 128 Reference< XInterface > SAL_CALL DBContentLoader::Create( const Reference< XMultiServiceFactory > & rSMgr ) 129 { 130 return *(new DBContentLoader(rSMgr)); 131 } 132 // ------------------------------------------------------------------------- 133 // XServiceInfo 134 ::rtl::OUString SAL_CALL DBContentLoader::getImplementationName() throw( ) 135 { 136 return getImplementationName_Static(); 137 } 138 // ------------------------------------------------------------------------- 139 140 // XServiceInfo 141 sal_Bool SAL_CALL DBContentLoader::supportsService(const ::rtl::OUString& ServiceName) throw( ) 142 { 143 Sequence< ::rtl::OUString > aSNL = getSupportedServiceNames(); 144 const ::rtl::OUString * pBegin = aSNL.getConstArray(); 145 const ::rtl::OUString * pEnd = pBegin + aSNL.getLength(); 146 for( ; pBegin != pEnd; ++pBegin) 147 if( *pBegin == ServiceName ) 148 return sal_True; 149 return sal_False; 150 } 151 // ------------------------------------------------------------------------- 152 // XServiceInfo 153 Sequence< ::rtl::OUString > SAL_CALL DBContentLoader::getSupportedServiceNames(void) throw( ) 154 { 155 return getSupportedServiceNames_Static(); 156 } 157 // ------------------------------------------------------------------------- 158 // ORegistryServiceManager_Static 159 Sequence< ::rtl::OUString > DBContentLoader::getSupportedServiceNames_Static(void) throw( ) 160 { 161 Sequence< ::rtl::OUString > aSNS( 2 ); 162 aSNS.getArray()[0] = ::rtl::OUString::createFromAscii("com.sun.star.frame.FrameLoader"); 163 aSNS.getArray()[1] = ::rtl::OUString::createFromAscii("com.sun.star.sdb.ContentLoader"); 164 return aSNS; 165 } 166 // ------------------------------------------------------------------------- 167 extern "C" void SAL_CALL writeDBLoaderInfo(void* pRegistryKey) 168 { 169 Reference< XRegistryKey> xKey(reinterpret_cast< XRegistryKey*>(pRegistryKey)); 170 171 // register content loader for dispatch 172 ::rtl::OUString aImpl = ::rtl::OUString::createFromAscii("/"); 173 aImpl += DBContentLoader::getImplementationName_Static(); 174 175 ::rtl::OUString aImpltwo = aImpl; 176 aImpltwo += ::rtl::OUString::createFromAscii("/UNO/Loader"); 177 Reference< XRegistryKey> xNewKey = xKey->createKey( aImpltwo ); 178 aImpltwo = aImpl; 179 aImpltwo += ::rtl::OUString::createFromAscii("/Loader"); 180 Reference< XRegistryKey > xLoaderKey = xKey->createKey( aImpltwo ); 181 xNewKey = xLoaderKey->createKey( ::rtl::OUString::createFromAscii("Pattern") ); 182 xNewKey->setAsciiValue( ::rtl::OUString::createFromAscii(".component:DB*") ); 183 } 184 185 // ----------------------------------------------------------------------- 186 void SAL_CALL DBContentLoader::load(const Reference< XFrame > & rFrame, const ::rtl::OUString& rURL, 187 const Sequence< PropertyValue >& rArgs, 188 const Reference< XLoadEventListener > & rListener) throw(::com::sun::star::uno::RuntimeException) 189 { 190 m_xFrame = rFrame; 191 m_xListener = rListener; 192 m_aURL = rURL; 193 m_aArgs = rArgs; 194 195 ::comphelper::ComponentContext aContext( m_xServiceFactory ); 196 197 struct ServiceNameToImplName 198 { 199 const sal_Char* pAsciiServiceName; 200 const sal_Char* pAsciiImplementationName; 201 ServiceNameToImplName( const sal_Char* _pService, const sal_Char* _pImpl ) 202 :pAsciiServiceName( _pService ) 203 ,pAsciiImplementationName( _pImpl ) 204 { 205 } 206 } aImplementations[] = { 207 ServiceNameToImplName( URL_COMPONENT_FORMGRIDVIEW, "org.openoffice.comp.dbu.OFormGridView" ), 208 ServiceNameToImplName( URL_COMPONENT_DATASOURCEBROWSER, "org.openoffice.comp.dbu.ODatasourceBrowser" ), 209 ServiceNameToImplName( URL_COMPONENT_QUERYDESIGN, "org.openoffice.comp.dbu.OQueryDesign" ), 210 ServiceNameToImplName( URL_COMPONENT_TABLEDESIGN, "org.openoffice.comp.dbu.OTableDesign" ), 211 ServiceNameToImplName( URL_COMPONENT_RELATIONDESIGN, "org.openoffice.comp.dbu.ORelationDesign" ), 212 ServiceNameToImplName( URL_COMPONENT_VIEWDESIGN, "org.openoffice.comp.dbu.OViewDesign" ) 213 }; 214 215 INetURLObject aParser( rURL ); 216 Reference< XController2 > xController; 217 218 const ::rtl::OUString sComponentURL( aParser.GetMainURL( INetURLObject::DECODE_TO_IURI ) ); 219 for ( size_t i=0; i < sizeof( aImplementations ) / sizeof( aImplementations[0] ); ++i ) 220 { 221 if ( sComponentURL.equalsAscii( aImplementations[i].pAsciiServiceName ) ) 222 { 223 aContext.createComponent( aImplementations[i].pAsciiImplementationName, xController ); 224 break; 225 } 226 } 227 228 // if a data source browser is loaded without its tree pane, then we assume it to be a 229 // table data view, effectively. In this case, we need to adjust the module identifier. 230 // 2008-02-05 / i85879 / frank.schoenheit@sun.com 231 ::comphelper::NamedValueCollection aLoadArgs( rArgs ); 232 233 if ( sComponentURL == URL_COMPONENT_DATASOURCEBROWSER ) 234 { 235 sal_Bool bDisableBrowser = ( sal_False == aLoadArgs.getOrDefault( "ShowTreeViewButton", sal_True ) ) // compatibility name 236 || ( sal_False == aLoadArgs.getOrDefault( (::rtl::OUString)PROPERTY_ENABLE_BROWSER, sal_True ) ); 237 238 if ( bDisableBrowser ) 239 { 240 try 241 { 242 Reference< XModule > xModule( xController, UNO_QUERY_THROW ); 243 xModule->setIdentifier( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.TableDataView" ) ) ); 244 } 245 catch( const Exception& ) 246 { 247 DBG_UNHANDLED_EXCEPTION(); 248 } 249 } 250 } 251 252 if ( sComponentURL == URL_COMPONENT_REPORTDESIGN ) 253 { 254 sal_Bool bPreview = aLoadArgs.getOrDefault( "Preview", sal_False ); 255 if ( bPreview ) 256 { // report designs cannot be previewed 257 if ( rListener.is() ) 258 rListener->loadCancelled( this ); 259 return; 260 } 261 Reference< XModel > xReportModel( aLoadArgs.getOrDefault( "Model", Reference< XModel >() ) ); 262 if ( xReportModel.is() ) 263 { 264 xController.set( m_xServiceFactory->createInstance( 265 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.ReportDesign" ) ) ), UNO_QUERY ); 266 if ( xController.is() ) 267 { 268 xController->attachModel( xReportModel ); 269 xReportModel->connectController( xController.get() ); 270 xReportModel->setCurrentController( xController.get() ); 271 } 272 } 273 } 274 275 sal_Bool bSuccess = xController.is(); 276 Reference< XModel > xDatabaseDocument; 277 if ( bSuccess ) 278 { 279 Reference< XDataSource > xDataSource ( aLoadArgs.getOrDefault( "DataSource", Reference< XDataSource >() ) ); 280 ::rtl::OUString sDataSourceName( aLoadArgs.getOrDefault( "DataSourceName", ::rtl::OUString() ) ); 281 Reference< XConnection > xConnection ( aLoadArgs.getOrDefault( "ActiveConnection", Reference< XConnection >() ) ); 282 if ( xDataSource.is() ) 283 { 284 xDatabaseDocument.set( getDataSourceOrModel( xDataSource ), UNO_QUERY ); 285 } 286 else if ( sDataSourceName.getLength() ) 287 { 288 ::dbtools::SQLExceptionInfo aError; 289 xDataSource.set( getDataSourceByName( sDataSourceName, NULL, m_xServiceFactory, &aError ) ); 290 xDatabaseDocument.set( getDataSourceOrModel( xDataSource ), UNO_QUERY ); 291 } 292 else if ( xConnection.is() ) 293 { 294 Reference< XChild > xAsChild( xConnection, UNO_QUERY ); 295 if ( xAsChild.is() ) 296 { 297 OSL_ENSURE( Reference< XDataSource >( xAsChild->getParent(), UNO_QUERY ).is(), 298 "DBContentLoader::load: a connection whose parent is no data source?" ); 299 xDatabaseDocument.set( getDataSourceOrModel( xAsChild->getParent() ), UNO_QUERY ); 300 } 301 } 302 303 // init controller 304 ::vos::OGuard aGuard(Application::GetSolarMutex()); 305 try 306 { 307 Reference<XInitialization > xIni(xController,UNO_QUERY); 308 PropertyValue aFrame(::rtl::OUString::createFromAscii("Frame"),0,makeAny(rFrame),PropertyState_DIRECT_VALUE); 309 Sequence< Any > aInitArgs(m_aArgs.getLength()+1); 310 311 Any* pBegin = aInitArgs.getArray(); 312 Any* pEnd = pBegin + aInitArgs.getLength(); 313 *pBegin <<= aFrame; 314 const PropertyValue* pIter = m_aArgs.getConstArray(); 315 for(++pBegin;pBegin != pEnd;++pBegin,++pIter) 316 { 317 *pBegin <<= *pIter; 318 } 319 320 xIni->initialize(aInitArgs); 321 } 322 catch(const Exception&) 323 { 324 // Does this need to be shown to the user? 325 bSuccess = false; 326 try 327 { 328 ::comphelper::disposeComponent( xController ); 329 } 330 catch( const Exception& ) 331 { 332 DBG_UNHANDLED_EXCEPTION(); 333 } 334 } 335 } 336 337 // assign controller and frame 338 if ( bSuccess ) 339 { 340 if ( xController.is() && rFrame.is() ) 341 { 342 rFrame->setComponent( xController->getComponentWindow(), xController.get() ); 343 xController->attachFrame(rFrame); 344 } 345 346 if ( rListener.is() ) 347 rListener->loadFinished( this ); 348 } 349 else 350 if ( rListener.is() ) 351 rListener->loadCancelled( this ); 352 } 353 354 // ----------------------------------------------------------------------- 355 void DBContentLoader::cancel(void) throw() 356 { 357 } 358 359