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_connectivity.hxx" 26 #include "calc/CConnection.hxx" 27 #include "calc/CDatabaseMetaData.hxx" 28 #include "calc/CCatalog.hxx" 29 #ifndef _CONNECTIVITY_CALC_ODRIVER_HXX_ 30 #include "calc/CDriver.hxx" 31 #endif 32 #ifndef CONNECTIVITY_RESOURCE_CALC_HRC 33 #include "resource/calc_res.hrc" 34 #endif 35 #include "resource/sharedresources.hxx" 36 #include <com/sun/star/lang/DisposedException.hpp> 37 #include <com/sun/star/frame/XComponentLoader.hpp> 38 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp> 39 #include <tools/urlobj.hxx> 40 #include "calc/CPreparedStatement.hxx" 41 #include "calc/CStatement.hxx" 42 #include <unotools/pathoptions.hxx> 43 #include <connectivity/dbexception.hxx> 44 #include <cppuhelper/exc_hlp.hxx> 45 #include <rtl/logfile.hxx> 46 47 using namespace connectivity::calc; 48 using namespace connectivity::file; 49 50 typedef connectivity::file::OConnection OConnection_BASE; 51 52 //------------------------------------------------------------------------------ 53 54 using namespace ::com::sun::star::uno; 55 using namespace ::com::sun::star::beans; 56 using namespace ::com::sun::star::sdbcx; 57 using namespace ::com::sun::star::sdbc; 58 using namespace ::com::sun::star::lang; 59 using namespace ::com::sun::star::frame; 60 using namespace ::com::sun::star::sheet; 61 62 // -------------------------------------------------------------------------------- 63 64 OCalcConnection::OCalcConnection(ODriver* _pDriver) : OConnection(_pDriver),m_nDocCount(0) 65 { 66 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::OCalcConnection" ); 67 // m_aFilenameExtension is not used 68 } 69 70 OCalcConnection::~OCalcConnection() 71 { 72 } 73 74 void OCalcConnection::construct(const ::rtl::OUString& url,const Sequence< PropertyValue >& info) 75 throw(SQLException) 76 { 77 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::construct" ); 78 // open file 79 80 sal_Int32 nLen = url.indexOf(':'); 81 nLen = url.indexOf(':',nLen+1); 82 ::rtl::OUString aDSN(url.copy(nLen+1)); 83 84 m_aFileName = aDSN; 85 INetURLObject aURL; 86 aURL.SetSmartProtocol(INET_PROT_FILE); 87 { 88 SvtPathOptions aPathOptions; 89 m_aFileName = aPathOptions.SubstituteVariable(m_aFileName); 90 } 91 aURL.SetSmartURL(m_aFileName); 92 if ( aURL.GetProtocol() == INET_PROT_NOT_VALID ) 93 { 94 // don't pass invalid URL to loadComponentFromURL 95 throw SQLException(); 96 } 97 m_aFileName = aURL.GetMainURL(INetURLObject::NO_DECODE); 98 99 m_sPassword = ::rtl::OUString(); 100 const char* pPwd = "password"; 101 102 const PropertyValue *pIter = info.getConstArray(); 103 const PropertyValue *pEnd = pIter + info.getLength(); 104 for(;pIter != pEnd;++pIter) 105 { 106 if(!pIter->Name.compareToAscii(pPwd)) 107 { 108 pIter->Value >>= m_sPassword; 109 break; 110 } 111 } // for(;pIter != pEnd;++pIter) 112 ODocHolder aDocHodler(this); // just to test that the doc can be loaded 113 acquireDoc(); 114 } 115 // ----------------------------------------------------------------------------- 116 Reference< XSpreadsheetDocument> OCalcConnection::acquireDoc() 117 { 118 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::acquireDoc" ); 119 if ( m_xDoc.is() ) 120 { 121 osl_incrementInterlockedCount(&m_nDocCount); 122 return m_xDoc; 123 } 124 // open read-only as long as updating isn't implemented 125 Sequence<PropertyValue> aArgs(2); 126 aArgs[0].Name = ::rtl::OUString::createFromAscii("Hidden"); 127 aArgs[0].Value <<= (sal_Bool) sal_True; 128 aArgs[1].Name = ::rtl::OUString::createFromAscii("ReadOnly"); 129 aArgs[1].Value <<= (sal_Bool) sal_True; 130 131 if ( m_sPassword.getLength() ) 132 { 133 const sal_Int32 nPos = aArgs.getLength(); 134 aArgs.realloc(nPos+1); 135 aArgs[nPos].Name = ::rtl::OUString::createFromAscii("Password"); 136 aArgs[nPos].Value <<= m_sPassword; 137 } 138 139 Reference< XComponentLoader > xDesktop( getDriver()->getFactory()->createInstance( 140 ::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop")), UNO_QUERY ); 141 if (!xDesktop.is()) 142 { 143 OSL_ASSERT("no desktop"); 144 throw SQLException(); 145 } 146 Reference< XComponent > xComponent; 147 Any aLoaderException; 148 try 149 { 150 xComponent = xDesktop->loadComponentFromURL( 151 m_aFileName, ::rtl::OUString::createFromAscii("_blank"), 0, aArgs ); 152 } 153 catch( const Exception& ) 154 { 155 aLoaderException = ::cppu::getCaughtException(); 156 } 157 158 m_xDoc.set(xComponent, UNO_QUERY ); 159 160 // if the URL is not a spreadsheet document, throw the exception here 161 // instead of at the first access to it 162 if ( !m_xDoc.is() ) 163 { 164 Any aErrorDetails; 165 if ( aLoaderException.hasValue() ) 166 { 167 Exception aLoaderError; 168 OSL_VERIFY( aLoaderException >>= aLoaderError ); 169 170 SQLException aDetailException; 171 aDetailException.Message = m_aResources.getResourceStringWithSubstitution( 172 STR_LOAD_FILE_ERROR_MESSAGE, 173 "$exception_type$", aLoaderException.getValueTypeName(), 174 "$error_message$", aLoaderError.Message 175 ); 176 aErrorDetails <<= aDetailException; 177 } 178 179 const ::rtl::OUString sError( m_aResources.getResourceStringWithSubstitution( 180 STR_COULD_NOT_LOAD_FILE, 181 "$filename$", m_aFileName 182 ) ); 183 ::dbtools::throwGenericSQLException( sError, *this, aErrorDetails ); 184 } 185 osl_incrementInterlockedCount(&m_nDocCount); 186 return m_xDoc; 187 } 188 // ----------------------------------------------------------------------------- 189 void OCalcConnection::releaseDoc() 190 { 191 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::releaseDoc" ); 192 if ( osl_decrementInterlockedCount(&m_nDocCount) == 0 ) 193 ::comphelper::disposeComponent( m_xDoc ); 194 } 195 // ----------------------------------------------------------------------------- 196 void OCalcConnection::disposing() 197 { 198 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::disposing" ); 199 ::osl::MutexGuard aGuard(m_aMutex); 200 201 m_nDocCount = 0; 202 ::comphelper::disposeComponent( m_xDoc ); 203 204 OConnection::disposing(); 205 } 206 207 // XServiceInfo 208 // -------------------------------------------------------------------------------- 209 210 IMPLEMENT_SERVICE_INFO(OCalcConnection, "com.sun.star.sdbc.drivers.calc.Connection", "com.sun.star.sdbc.Connection") 211 212 // -------------------------------------------------------------------------------- 213 214 Reference< XDatabaseMetaData > SAL_CALL OCalcConnection::getMetaData( ) throw(SQLException, RuntimeException) 215 { 216 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::getMetaData" ); 217 ::osl::MutexGuard aGuard( m_aMutex ); 218 checkDisposed(OConnection_BASE::rBHelper.bDisposed); 219 220 221 Reference< XDatabaseMetaData > xMetaData = m_xMetaData; 222 if(!xMetaData.is()) 223 { 224 xMetaData = new OCalcDatabaseMetaData(this); 225 m_xMetaData = xMetaData; 226 } 227 228 return xMetaData; 229 } 230 231 //------------------------------------------------------------------------------ 232 233 ::com::sun::star::uno::Reference< XTablesSupplier > OCalcConnection::createCatalog() 234 { 235 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::createCatalog" ); 236 ::osl::MutexGuard aGuard( m_aMutex ); 237 Reference< XTablesSupplier > xTab = m_xCatalog; 238 if(!xTab.is()) 239 { 240 OCalcCatalog *pCat = new OCalcCatalog(this); 241 xTab = pCat; 242 m_xCatalog = xTab; 243 } 244 return xTab; 245 } 246 247 // -------------------------------------------------------------------------------- 248 249 Reference< XStatement > SAL_CALL OCalcConnection::createStatement( ) throw(SQLException, RuntimeException) 250 { 251 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::createStatement" ); 252 ::osl::MutexGuard aGuard( m_aMutex ); 253 checkDisposed(OConnection_BASE::rBHelper.bDisposed); 254 255 256 Reference< XStatement > xReturn = new OCalcStatement(this); 257 m_aStatements.push_back(WeakReferenceHelper(xReturn)); 258 return xReturn; 259 } 260 261 // -------------------------------------------------------------------------------- 262 263 Reference< XPreparedStatement > SAL_CALL OCalcConnection::prepareStatement( const ::rtl::OUString& sql ) 264 throw(SQLException, RuntimeException) 265 { 266 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::prepareStatement" ); 267 ::osl::MutexGuard aGuard( m_aMutex ); 268 checkDisposed(OConnection_BASE::rBHelper.bDisposed); 269 270 271 OCalcPreparedStatement* pStmt = new OCalcPreparedStatement(this); 272 Reference< XPreparedStatement > xHoldAlive = pStmt; 273 pStmt->construct(sql); 274 m_aStatements.push_back(WeakReferenceHelper(*pStmt)); 275 return pStmt; 276 } 277 278 // -------------------------------------------------------------------------------- 279 280 Reference< XPreparedStatement > SAL_CALL OCalcConnection::prepareCall( const ::rtl::OUString& /*sql*/ ) 281 throw(SQLException, RuntimeException) 282 { 283 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::prepareCall" ); 284 ::osl::MutexGuard aGuard( m_aMutex ); 285 checkDisposed(OConnection_BASE::rBHelper.bDisposed); 286 287 ::dbtools::throwFeatureNotImplementedException( "XConnection::prepareCall", *this ); 288 return NULL; 289 } 290 // ----------------------------------------------------------------------------- 291 292