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