/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_connectivity.hxx" #include "calc/CConnection.hxx" #include "calc/CDatabaseMetaData.hxx" #include "calc/CCatalog.hxx" #ifndef _CONNECTIVITY_CALC_ODRIVER_HXX_ #include "calc/CDriver.hxx" #endif #ifndef CONNECTIVITY_RESOURCE_CALC_HRC #include "resource/calc_res.hrc" #endif #include "resource/sharedresources.hxx" #include #include #include #include #include "calc/CPreparedStatement.hxx" #include "calc/CStatement.hxx" #include #include #include #include using namespace connectivity::calc; using namespace connectivity::file; typedef connectivity::file::OConnection OConnection_BASE; //------------------------------------------------------------------------------ using namespace ::com::sun::star::uno; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::sdbcx; using namespace ::com::sun::star::sdbc; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::frame; using namespace ::com::sun::star::sheet; // -------------------------------------------------------------------------------- OCalcConnection::OCalcConnection(ODriver* _pDriver) : OConnection(_pDriver),m_nDocCount(0) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::OCalcConnection" ); // m_aFilenameExtension is not used } OCalcConnection::~OCalcConnection() { } void OCalcConnection::construct(const ::rtl::OUString& url,const Sequence< PropertyValue >& info) throw(SQLException) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::construct" ); // open file sal_Int32 nLen = url.indexOf(':'); nLen = url.indexOf(':',nLen+1); ::rtl::OUString aDSN(url.copy(nLen+1)); m_aFileName = aDSN; INetURLObject aURL; aURL.SetSmartProtocol(INET_PROT_FILE); { SvtPathOptions aPathOptions; m_aFileName = aPathOptions.SubstituteVariable(m_aFileName); } aURL.SetSmartURL(m_aFileName); if ( aURL.GetProtocol() == INET_PROT_NOT_VALID ) { // don't pass invalid URL to loadComponentFromURL throw SQLException(); } m_aFileName = aURL.GetMainURL(INetURLObject::NO_DECODE); m_sPassword = ::rtl::OUString(); const char* pPwd = "password"; const PropertyValue *pIter = info.getConstArray(); const PropertyValue *pEnd = pIter + info.getLength(); for(;pIter != pEnd;++pIter) { if(!pIter->Name.compareToAscii(pPwd)) { pIter->Value >>= m_sPassword; break; } } // for(;pIter != pEnd;++pIter) ODocHolder aDocHodler(this); // just to test that the doc can be loaded acquireDoc(); } // ----------------------------------------------------------------------------- Reference< XSpreadsheetDocument> OCalcConnection::acquireDoc() { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::acquireDoc" ); if ( m_xDoc.is() ) { osl_incrementInterlockedCount(&m_nDocCount); return m_xDoc; } // open read-only as long as updating isn't implemented Sequence aArgs(2); aArgs[0].Name = ::rtl::OUString::createFromAscii("Hidden"); aArgs[0].Value <<= (sal_Bool) sal_True; aArgs[1].Name = ::rtl::OUString::createFromAscii("ReadOnly"); aArgs[1].Value <<= (sal_Bool) sal_True; if ( m_sPassword.getLength() ) { const sal_Int32 nPos = aArgs.getLength(); aArgs.realloc(nPos+1); aArgs[nPos].Name = ::rtl::OUString::createFromAscii("Password"); aArgs[nPos].Value <<= m_sPassword; } Reference< XComponentLoader > xDesktop( getDriver()->getFactory()->createInstance( ::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop")), UNO_QUERY ); if (!xDesktop.is()) { OSL_ASSERT("no desktop"); throw SQLException(); } Reference< XComponent > xComponent; Any aLoaderException; try { xComponent = xDesktop->loadComponentFromURL( m_aFileName, ::rtl::OUString::createFromAscii("_blank"), 0, aArgs ); } catch( const Exception& ) { aLoaderException = ::cppu::getCaughtException(); } m_xDoc.set(xComponent, UNO_QUERY ); // if the URL is not a spreadsheet document, throw the exception here // instead of at the first access to it if ( !m_xDoc.is() ) { Any aErrorDetails; if ( aLoaderException.hasValue() ) { Exception aLoaderError; OSL_VERIFY( aLoaderException >>= aLoaderError ); SQLException aDetailException; aDetailException.Message = m_aResources.getResourceStringWithSubstitution( STR_LOAD_FILE_ERROR_MESSAGE, "$exception_type$", aLoaderException.getValueTypeName(), "$error_message$", aLoaderError.Message ); aErrorDetails <<= aDetailException; } const ::rtl::OUString sError( m_aResources.getResourceStringWithSubstitution( STR_COULD_NOT_LOAD_FILE, "$filename$", m_aFileName ) ); ::dbtools::throwGenericSQLException( sError, *this, aErrorDetails ); } osl_incrementInterlockedCount(&m_nDocCount); return m_xDoc; } // ----------------------------------------------------------------------------- void OCalcConnection::releaseDoc() { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::releaseDoc" ); if ( osl_decrementInterlockedCount(&m_nDocCount) == 0 ) ::comphelper::disposeComponent( m_xDoc ); } // ----------------------------------------------------------------------------- void OCalcConnection::disposing() { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::disposing" ); ::osl::MutexGuard aGuard(m_aMutex); m_nDocCount = 0; ::comphelper::disposeComponent( m_xDoc ); OConnection::disposing(); } // XServiceInfo // -------------------------------------------------------------------------------- IMPLEMENT_SERVICE_INFO(OCalcConnection, "com.sun.star.sdbc.drivers.calc.Connection", "com.sun.star.sdbc.Connection") // -------------------------------------------------------------------------------- Reference< XDatabaseMetaData > SAL_CALL OCalcConnection::getMetaData( ) throw(SQLException, RuntimeException) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::getMetaData" ); ::osl::MutexGuard aGuard( m_aMutex ); checkDisposed(OConnection_BASE::rBHelper.bDisposed); Reference< XDatabaseMetaData > xMetaData = m_xMetaData; if(!xMetaData.is()) { xMetaData = new OCalcDatabaseMetaData(this); m_xMetaData = xMetaData; } return xMetaData; } //------------------------------------------------------------------------------ ::com::sun::star::uno::Reference< XTablesSupplier > OCalcConnection::createCatalog() { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::createCatalog" ); ::osl::MutexGuard aGuard( m_aMutex ); Reference< XTablesSupplier > xTab = m_xCatalog; if(!xTab.is()) { OCalcCatalog *pCat = new OCalcCatalog(this); xTab = pCat; m_xCatalog = xTab; } return xTab; } // -------------------------------------------------------------------------------- Reference< XStatement > SAL_CALL OCalcConnection::createStatement( ) throw(SQLException, RuntimeException) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::createStatement" ); ::osl::MutexGuard aGuard( m_aMutex ); checkDisposed(OConnection_BASE::rBHelper.bDisposed); Reference< XStatement > xReturn = new OCalcStatement(this); m_aStatements.push_back(WeakReferenceHelper(xReturn)); return xReturn; } // -------------------------------------------------------------------------------- Reference< XPreparedStatement > SAL_CALL OCalcConnection::prepareStatement( const ::rtl::OUString& sql ) throw(SQLException, RuntimeException) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::prepareStatement" ); ::osl::MutexGuard aGuard( m_aMutex ); checkDisposed(OConnection_BASE::rBHelper.bDisposed); OCalcPreparedStatement* pStmt = new OCalcPreparedStatement(this); Reference< XPreparedStatement > xHoldAlive = pStmt; pStmt->construct(sql); m_aStatements.push_back(WeakReferenceHelper(*pStmt)); return pStmt; } // -------------------------------------------------------------------------------- Reference< XPreparedStatement > SAL_CALL OCalcConnection::prepareCall( const ::rtl::OUString& /*sql*/ ) throw(SQLException, RuntimeException) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::prepareCall" ); ::osl::MutexGuard aGuard( m_aMutex ); checkDisposed(OConnection_BASE::rBHelper.bDisposed); ::dbtools::throwFeatureNotImplementedException( "XConnection::prepareCall", *this ); return NULL; } // -----------------------------------------------------------------------------