1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "calc/CConnection.hxx"
21 #include "calc/CDatabaseMetaData.hxx"
22 #include "calc/CCatalog.hxx"
23 #include "calc/CDriver.hxx"
24 #include "resource/calc_res.hrc"
25 #include "resource/sharedresources.hxx"
26 #include <com/sun/star/lang/DisposedException.hpp>
27 #include <com/sun/star/frame/Desktop.hpp>
28 #include <com/sun/star/frame/XComponentLoader.hpp>
29 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
30 #include <tools/urlobj.hxx>
31 #include "calc/CPreparedStatement.hxx"
32 #include "calc/CStatement.hxx"
33 #include <unotools/pathoptions.hxx>
34 #include <connectivity/dbexception.hxx>
35 #include <cppuhelper/exc_hlp.hxx>
36 #include <comphelper/processfactory.hxx>
38 using namespace connectivity::calc
;
39 using namespace connectivity::file
;
41 typedef connectivity::file::OConnection OConnection_BASE
;
45 using namespace ::com::sun::star::uno
;
46 using namespace ::com::sun::star::beans
;
47 using namespace ::com::sun::star::sdbcx
;
48 using namespace ::com::sun::star::sdbc
;
49 using namespace ::com::sun::star::lang
;
50 using namespace ::com::sun::star::frame
;
51 using namespace ::com::sun::star::sheet
;
55 OCalcConnection::OCalcConnection(ODriver
* _pDriver
) : OConnection(_pDriver
),m_nDocCount(0)
57 // m_aFilenameExtension is not used
60 OCalcConnection::~OCalcConnection()
64 void OCalcConnection::construct(const OUString
& url
,const Sequence
< PropertyValue
>& info
)
65 throw(SQLException
, RuntimeException
, DeploymentException
)
69 sal_Int32 nLen
= url
.indexOf(':');
70 nLen
= url
.indexOf(':',nLen
+1);
71 OUString
aDSN(url
.copy(nLen
+1));
75 aURL
.SetSmartProtocol(INET_PROT_FILE
);
77 SvtPathOptions aPathOptions
;
78 m_aFileName
= aPathOptions
.SubstituteVariable(m_aFileName
);
80 aURL
.SetSmartURL(m_aFileName
);
81 if ( aURL
.GetProtocol() == INET_PROT_NOT_VALID
)
83 // don't pass invalid URL to loadComponentFromURL
86 m_aFileName
= aURL
.GetMainURL(INetURLObject::NO_DECODE
);
89 const char* pPwd
= "password";
91 const PropertyValue
*pIter
= info
.getConstArray();
92 const PropertyValue
*pEnd
= pIter
+ info
.getLength();
93 for(;pIter
!= pEnd
;++pIter
)
95 if(pIter
->Name
.equalsAscii(pPwd
))
97 pIter
->Value
>>= m_sPassword
;
100 } // for(;pIter != pEnd;++pIter)
101 ODocHolder
aDocHodler(this); // just to test that the doc can be loaded
105 Reference
< XSpreadsheetDocument
> OCalcConnection::acquireDoc()
109 osl_atomic_increment(&m_nDocCount
);
112 // open read-only as long as updating isn't implemented
113 Sequence
<PropertyValue
> aArgs(2);
114 aArgs
[0].Name
= "Hidden";
115 aArgs
[0].Value
<<= true;
116 aArgs
[1].Name
= "ReadOnly";
117 aArgs
[1].Value
<<= true;
119 if ( !m_sPassword
.isEmpty() )
121 const sal_Int32 nPos
= aArgs
.getLength();
122 aArgs
.realloc(nPos
+1);
123 aArgs
[nPos
].Name
= "Password";
124 aArgs
[nPos
].Value
<<= m_sPassword
;
127 Reference
< XDesktop2
> xDesktop
= Desktop::create( getDriver()->getComponentContext() );
128 Reference
< XComponent
> xComponent
;
129 Any aLoaderException
;
132 xComponent
= xDesktop
->loadComponentFromURL(
133 m_aFileName
, OUString("_blank"), 0, aArgs
);
135 catch( const Exception
& )
137 aLoaderException
= ::cppu::getCaughtException();
140 m_xDoc
.set(xComponent
, UNO_QUERY
);
142 // if the URL is not a spreadsheet document, throw the exception here
143 // instead of at the first access to it
147 if ( aLoaderException
.hasValue() )
149 Exception aLoaderError
;
150 OSL_VERIFY( aLoaderException
>>= aLoaderError
);
152 SQLException aDetailException
;
153 aDetailException
.Message
= m_aResources
.getResourceStringWithSubstitution(
154 STR_LOAD_FILE_ERROR_MESSAGE
,
155 "$exception_type$", aLoaderException
.getValueTypeName(),
156 "$error_message$", aLoaderError
.Message
158 aErrorDetails
<<= aDetailException
;
161 const OUString
sError( m_aResources
.getResourceStringWithSubstitution(
162 STR_COULD_NOT_LOAD_FILE
,
163 "$filename$", m_aFileName
165 ::dbtools::throwGenericSQLException( sError
, *this, aErrorDetails
);
167 osl_atomic_increment(&m_nDocCount
);
171 void OCalcConnection::releaseDoc()
173 if ( osl_atomic_decrement(&m_nDocCount
) == 0 )
174 ::comphelper::disposeComponent( m_xDoc
);
177 void OCalcConnection::disposing()
179 ::osl::MutexGuard
aGuard(m_aMutex
);
182 ::comphelper::disposeComponent( m_xDoc
);
184 OConnection::disposing();
190 IMPLEMENT_SERVICE_INFO(OCalcConnection
, "com.sun.star.sdbc.drivers.calc.Connection", "com.sun.star.sdbc.Connection")
194 Reference
< XDatabaseMetaData
> SAL_CALL
OCalcConnection::getMetaData( ) throw(SQLException
, RuntimeException
, std::exception
)
196 ::osl::MutexGuard
aGuard( m_aMutex
);
197 checkDisposed(OConnection_BASE::rBHelper
.bDisposed
);
200 Reference
< XDatabaseMetaData
> xMetaData
= m_xMetaData
;
203 xMetaData
= new OCalcDatabaseMetaData(this);
204 m_xMetaData
= xMetaData
;
212 ::com::sun::star::uno::Reference
< XTablesSupplier
> OCalcConnection::createCatalog()
214 ::osl::MutexGuard
aGuard( m_aMutex
);
215 Reference
< XTablesSupplier
> xTab
= m_xCatalog
;
218 OCalcCatalog
*pCat
= new OCalcCatalog(this);
227 Reference
< XStatement
> SAL_CALL
OCalcConnection::createStatement( ) throw(SQLException
, RuntimeException
, std::exception
)
229 ::osl::MutexGuard
aGuard( m_aMutex
);
230 checkDisposed(OConnection_BASE::rBHelper
.bDisposed
);
233 Reference
< XStatement
> xReturn
= new OCalcStatement(this);
234 m_aStatements
.push_back(WeakReferenceHelper(xReturn
));
240 Reference
< XPreparedStatement
> SAL_CALL
OCalcConnection::prepareStatement( const OUString
& sql
)
241 throw(SQLException
, RuntimeException
, std::exception
)
243 ::osl::MutexGuard
aGuard( m_aMutex
);
244 checkDisposed(OConnection_BASE::rBHelper
.bDisposed
);
247 OCalcPreparedStatement
* pStmt
= new OCalcPreparedStatement(this);
248 Reference
< XPreparedStatement
> xHoldAlive
= pStmt
;
249 pStmt
->construct(sql
);
250 m_aStatements
.push_back(WeakReferenceHelper(*pStmt
));
256 Reference
< XPreparedStatement
> SAL_CALL
OCalcConnection::prepareCall( const OUString
& /*sql*/ )
257 throw(SQLException
, RuntimeException
, std::exception
)
259 ::osl::MutexGuard
aGuard( m_aMutex
);
260 checkDisposed(OConnection_BASE::rBHelper
.bDisposed
);
262 ::dbtools::throwFeatureNotImplementedException( "XConnection::prepareCall", *this );
267 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */