xref: /trunk/main/connectivity/source/drivers/hsqldb/HDriver.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_connectivity.hxx"
30*cdf0e10cSrcweir #include "hsqldb/HDriver.hxx"
31*cdf0e10cSrcweir #include "hsqldb/HConnection.hxx"
32*cdf0e10cSrcweir #include <osl/diagnose.h>
33*cdf0e10cSrcweir #include "connectivity/dbexception.hxx"
34*cdf0e10cSrcweir #include <com/sun/star/sdbc/XDriverAccess.hpp>
35*cdf0e10cSrcweir #include <com/sun/star/sdbc/XResultSet.hpp>
36*cdf0e10cSrcweir #include <com/sun/star/sdbc/XRow.hpp>
37*cdf0e10cSrcweir #include <com/sun/star/embed/XTransactionBroadcaster.hpp>
38*cdf0e10cSrcweir #include <com/sun/star/embed/ElementModes.hpp>
39*cdf0e10cSrcweir #include "TConnection.hxx"
40*cdf0e10cSrcweir #include "hsqldb/HStorageMap.hxx"
41*cdf0e10cSrcweir #include <jvmfwk/framework.h>
42*cdf0e10cSrcweir #include <com/sun/star/reflection/XProxyFactory.hpp>
43*cdf0e10cSrcweir #include <com/sun/star/embed/XStorage.hpp>
44*cdf0e10cSrcweir #include <com/sun/star/frame/XDesktop.hpp>
45*cdf0e10cSrcweir #include <com/sun/star/lang/Locale.hpp>
46*cdf0e10cSrcweir #include <com/sun/star/util/XFlushable.hpp>
47*cdf0e10cSrcweir #include "HTerminateListener.hxx"
48*cdf0e10cSrcweir #include "hsqldb/HCatalog.hxx"
49*cdf0e10cSrcweir #include "diagnose_ex.h"
50*cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
51*cdf0e10cSrcweir #include <osl/file.h>
52*cdf0e10cSrcweir #include <osl/process.h>
53*cdf0e10cSrcweir #include <connectivity/dbexception.hxx>
54*cdf0e10cSrcweir #include <comphelper/namedvaluecollection.hxx>
55*cdf0e10cSrcweir #include <unotools/confignode.hxx>
56*cdf0e10cSrcweir #include <unotools/ucbstreamhelper.hxx>
57*cdf0e10cSrcweir #include "resource/hsqldb_res.hrc"
58*cdf0e10cSrcweir #include "resource/sharedresources.hxx"
59*cdf0e10cSrcweir 
60*cdf0e10cSrcweir //........................................................................
61*cdf0e10cSrcweir namespace connectivity
62*cdf0e10cSrcweir {
63*cdf0e10cSrcweir //........................................................................
64*cdf0e10cSrcweir     using namespace hsqldb;
65*cdf0e10cSrcweir     using namespace ::com::sun::star::uno;
66*cdf0e10cSrcweir     using namespace ::com::sun::star::sdbc;
67*cdf0e10cSrcweir     using namespace ::com::sun::star::sdbcx;
68*cdf0e10cSrcweir     using namespace ::com::sun::star::beans;
69*cdf0e10cSrcweir     using namespace ::com::sun::star::frame;
70*cdf0e10cSrcweir     using namespace ::com::sun::star::lang;
71*cdf0e10cSrcweir     using namespace ::com::sun::star::embed;
72*cdf0e10cSrcweir     using namespace ::com::sun::star::io;
73*cdf0e10cSrcweir     using namespace ::com::sun::star::task;
74*cdf0e10cSrcweir     using namespace ::com::sun::star::util;
75*cdf0e10cSrcweir     using namespace ::com::sun::star::reflection;
76*cdf0e10cSrcweir 
77*cdf0e10cSrcweir     namespace hsqldb
78*cdf0e10cSrcweir     {
79*cdf0e10cSrcweir         Reference< XInterface >  SAL_CALL ODriverDelegator_CreateInstance(const Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFac) throw( Exception )
80*cdf0e10cSrcweir         {
81*cdf0e10cSrcweir             return *(new ODriverDelegator(_rxFac));
82*cdf0e10cSrcweir         }
83*cdf0e10cSrcweir     }
84*cdf0e10cSrcweir 
85*cdf0e10cSrcweir 
86*cdf0e10cSrcweir 
87*cdf0e10cSrcweir     //====================================================================
88*cdf0e10cSrcweir     //= ODriverDelegator
89*cdf0e10cSrcweir     //====================================================================
90*cdf0e10cSrcweir     //--------------------------------------------------------------------
91*cdf0e10cSrcweir     ODriverDelegator::ODriverDelegator(const Reference< XMultiServiceFactory >& _rxFactory)
92*cdf0e10cSrcweir         : ODriverDelegator_BASE(m_aMutex)
93*cdf0e10cSrcweir         ,m_xFactory(_rxFactory)
94*cdf0e10cSrcweir         ,m_bInShutDownConnections(sal_False)
95*cdf0e10cSrcweir     {
96*cdf0e10cSrcweir     }
97*cdf0e10cSrcweir 
98*cdf0e10cSrcweir     //--------------------------------------------------------------------
99*cdf0e10cSrcweir     ODriverDelegator::~ODriverDelegator()
100*cdf0e10cSrcweir     {
101*cdf0e10cSrcweir         try
102*cdf0e10cSrcweir         {
103*cdf0e10cSrcweir             ::comphelper::disposeComponent(m_xDriver);
104*cdf0e10cSrcweir         }
105*cdf0e10cSrcweir         catch(const Exception&)
106*cdf0e10cSrcweir         {
107*cdf0e10cSrcweir         }
108*cdf0e10cSrcweir     }
109*cdf0e10cSrcweir 
110*cdf0e10cSrcweir     // --------------------------------------------------------------------------------
111*cdf0e10cSrcweir     void SAL_CALL ODriverDelegator::disposing()
112*cdf0e10cSrcweir     {
113*cdf0e10cSrcweir         ::osl::MutexGuard aGuard(m_aMutex);
114*cdf0e10cSrcweir 
115*cdf0e10cSrcweir         try
116*cdf0e10cSrcweir         {
117*cdf0e10cSrcweir             for (TWeakPairVector::iterator i = m_aConnections.begin(); m_aConnections.end() != i; ++i)
118*cdf0e10cSrcweir             {
119*cdf0e10cSrcweir                 Reference<XInterface > xTemp = i->first.get();
120*cdf0e10cSrcweir                 ::comphelper::disposeComponent(xTemp);
121*cdf0e10cSrcweir             }
122*cdf0e10cSrcweir         }
123*cdf0e10cSrcweir         catch(Exception&)
124*cdf0e10cSrcweir         {
125*cdf0e10cSrcweir             // not interested in
126*cdf0e10cSrcweir         }
127*cdf0e10cSrcweir         m_aConnections.clear();
128*cdf0e10cSrcweir         TWeakPairVector().swap(m_aConnections);
129*cdf0e10cSrcweir 
130*cdf0e10cSrcweir         cppu::WeakComponentImplHelperBase::disposing();
131*cdf0e10cSrcweir     }
132*cdf0e10cSrcweir     //--------------------------------------------------------------------
133*cdf0e10cSrcweir     Reference< XDriver > ODriverDelegator::loadDriver( )
134*cdf0e10cSrcweir     {
135*cdf0e10cSrcweir         if ( !m_xDriver.is() )
136*cdf0e10cSrcweir         {
137*cdf0e10cSrcweir             ::rtl::OUString sURL(RTL_CONSTASCII_USTRINGPARAM("jdbc:hsqldb:db"));
138*cdf0e10cSrcweir             Reference<XDriverAccess> xDriverAccess(m_xFactory->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdbc.DriverManager")) ),UNO_QUERY);
139*cdf0e10cSrcweir             OSL_ENSURE(xDriverAccess.is(),"Could not load driver manager!");
140*cdf0e10cSrcweir             if ( xDriverAccess.is() )
141*cdf0e10cSrcweir                 m_xDriver = xDriverAccess->getDriverByURL(sURL);
142*cdf0e10cSrcweir         }
143*cdf0e10cSrcweir 
144*cdf0e10cSrcweir         return m_xDriver;
145*cdf0e10cSrcweir     }
146*cdf0e10cSrcweir 
147*cdf0e10cSrcweir     //--------------------------------------------------------------------
148*cdf0e10cSrcweir     namespace
149*cdf0e10cSrcweir     {
150*cdf0e10cSrcweir         ::rtl::OUString lcl_getPermittedJavaMethods_nothrow( const Reference< XMultiServiceFactory >& _rxORB )
151*cdf0e10cSrcweir         {
152*cdf0e10cSrcweir             ::rtl::OUStringBuffer aConfigPath;
153*cdf0e10cSrcweir             aConfigPath.appendAscii( "/org.openoffice.Office.DataAccess/DriverSettings/" );
154*cdf0e10cSrcweir             aConfigPath.append     ( ODriverDelegator::getImplementationName_Static() );
155*cdf0e10cSrcweir             aConfigPath.appendAscii( "/PermittedJavaMethods" );
156*cdf0e10cSrcweir             ::utl::OConfigurationTreeRoot aConfig( ::utl::OConfigurationTreeRoot::createWithServiceFactory(
157*cdf0e10cSrcweir                 _rxORB, aConfigPath.makeStringAndClear() ) );
158*cdf0e10cSrcweir 
159*cdf0e10cSrcweir             ::rtl::OUStringBuffer aPermittedMethods;
160*cdf0e10cSrcweir             Sequence< ::rtl::OUString > aNodeNames( aConfig.getNodeNames() );
161*cdf0e10cSrcweir             for (   const ::rtl::OUString* pNodeNames = aNodeNames.getConstArray();
162*cdf0e10cSrcweir                     pNodeNames != aNodeNames.getConstArray() + aNodeNames.getLength();
163*cdf0e10cSrcweir                     ++pNodeNames
164*cdf0e10cSrcweir                 )
165*cdf0e10cSrcweir             {
166*cdf0e10cSrcweir                 ::rtl::OUString sPermittedMethod;
167*cdf0e10cSrcweir                 OSL_VERIFY( aConfig.getNodeValue( *pNodeNames ) >>= sPermittedMethod );
168*cdf0e10cSrcweir 
169*cdf0e10cSrcweir                 if ( aPermittedMethods.getLength() )
170*cdf0e10cSrcweir                     aPermittedMethods.append( (sal_Unicode)';' );
171*cdf0e10cSrcweir                 aPermittedMethods.append( sPermittedMethod );
172*cdf0e10cSrcweir             }
173*cdf0e10cSrcweir 
174*cdf0e10cSrcweir             return aPermittedMethods.makeStringAndClear();;
175*cdf0e10cSrcweir         }
176*cdf0e10cSrcweir     }
177*cdf0e10cSrcweir 
178*cdf0e10cSrcweir     //--------------------------------------------------------------------
179*cdf0e10cSrcweir     Reference< XConnection > SAL_CALL ODriverDelegator::connect( const ::rtl::OUString& url, const Sequence< PropertyValue >& info ) throw (SQLException, RuntimeException)
180*cdf0e10cSrcweir     {
181*cdf0e10cSrcweir         Reference< XConnection > xConnection;
182*cdf0e10cSrcweir         if ( acceptsURL(url) )
183*cdf0e10cSrcweir         {
184*cdf0e10cSrcweir             Reference< XDriver > xDriver = loadDriver();
185*cdf0e10cSrcweir             if ( xDriver.is() )
186*cdf0e10cSrcweir             {
187*cdf0e10cSrcweir                 ::rtl::OUString sURL;
188*cdf0e10cSrcweir                 Reference<XStorage> xStorage;
189*cdf0e10cSrcweir                 const PropertyValue* pIter = info.getConstArray();
190*cdf0e10cSrcweir                 const PropertyValue* pEnd = pIter + info.getLength();
191*cdf0e10cSrcweir 
192*cdf0e10cSrcweir                 for (;pIter != pEnd; ++pIter)
193*cdf0e10cSrcweir                 {
194*cdf0e10cSrcweir                     if ( pIter->Name.equalsAscii("Storage") )
195*cdf0e10cSrcweir                     {
196*cdf0e10cSrcweir                         xStorage.set(pIter->Value,UNO_QUERY);
197*cdf0e10cSrcweir                     }
198*cdf0e10cSrcweir                     else if ( pIter->Name.equalsAscii("URL") )
199*cdf0e10cSrcweir                     {
200*cdf0e10cSrcweir                         pIter->Value >>= sURL;
201*cdf0e10cSrcweir                     }
202*cdf0e10cSrcweir                 }
203*cdf0e10cSrcweir 
204*cdf0e10cSrcweir                 if ( !xStorage.is() || !sURL.getLength() )
205*cdf0e10cSrcweir                 {
206*cdf0e10cSrcweir                     ::connectivity::SharedResources aResources;
207*cdf0e10cSrcweir                     const ::rtl::OUString sMessage = aResources.getResourceString(STR_NO_STROAGE);
208*cdf0e10cSrcweir                     ::dbtools::throwGenericSQLException(sMessage ,*this);
209*cdf0e10cSrcweir                 }
210*cdf0e10cSrcweir 
211*cdf0e10cSrcweir                 ::rtl::OUString sSystemPath;
212*cdf0e10cSrcweir                 osl_getSystemPathFromFileURL( sURL.pData, &sSystemPath.pData );
213*cdf0e10cSrcweir                 sal_Int32 nIndex = sSystemPath.lastIndexOf('.');
214*cdf0e10cSrcweir                 if ( !sURL.getLength() || !sSystemPath.getLength() )
215*cdf0e10cSrcweir                 {
216*cdf0e10cSrcweir                     ::connectivity::SharedResources aResources;
217*cdf0e10cSrcweir                     const ::rtl::OUString sMessage = aResources.getResourceString(STR_INVALID_FILE_URL);
218*cdf0e10cSrcweir                     ::dbtools::throwGenericSQLException(sMessage ,*this);
219*cdf0e10cSrcweir                 }
220*cdf0e10cSrcweir 
221*cdf0e10cSrcweir                 bool bIsNewDatabase = !xStorage->hasElements();
222*cdf0e10cSrcweir 
223*cdf0e10cSrcweir                 ::comphelper::NamedValueCollection aProperties;
224*cdf0e10cSrcweir 
225*cdf0e10cSrcweir                 // properties for accessing the embedded storage
226*cdf0e10cSrcweir                 ::rtl::OUString sConnPartURL = sSystemPath.copy( 0, ::std::max< sal_Int32 >( nIndex, sSystemPath.getLength() ) );
227*cdf0e10cSrcweir                 ::rtl::OUString sKey = StorageContainer::registerStorage( xStorage, sConnPartURL );
228*cdf0e10cSrcweir                 aProperties.put( "storage_key", sKey );
229*cdf0e10cSrcweir                 aProperties.put( "storage_class_name",
230*cdf0e10cSrcweir                     ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdbcx.comp.hsqldb.StorageAccess" ) ) );
231*cdf0e10cSrcweir                 aProperties.put( "fileaccess_class_name",
232*cdf0e10cSrcweir                     ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdbcx.comp.hsqldb.StorageFileAccess" ) ) );
233*cdf0e10cSrcweir 
234*cdf0e10cSrcweir                 // JDBC driver and driver's classpath
235*cdf0e10cSrcweir                 aProperties.put( "JavaDriverClass",
236*cdf0e10cSrcweir                     ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "org.hsqldb.jdbcDriver" ) ) );
237*cdf0e10cSrcweir                 aProperties.put( "JavaDriverClassPath",
238*cdf0e10cSrcweir                     ::rtl::OUString(
239*cdf0e10cSrcweir #ifdef SYSTEM_HSQLDB
240*cdf0e10cSrcweir                         RTL_CONSTASCII_USTRINGPARAM(HSQLDB_JAR
241*cdf0e10cSrcweir                         " vnd.sun.star.expand:$OOO_BASE_DIR/program/classes/sdbc_hsqldb.jar" )
242*cdf0e10cSrcweir #else
243*cdf0e10cSrcweir                         RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.expand:$OOO_BASE_DIR/program/classes/hsqldb.jar"
244*cdf0e10cSrcweir                         " vnd.sun.star.expand:$OOO_BASE_DIR/program/classes/sdbc_hsqldb.jar" )
245*cdf0e10cSrcweir #endif
246*cdf0e10cSrcweir                         ) );
247*cdf0e10cSrcweir 
248*cdf0e10cSrcweir                 // auto increment handling
249*cdf0e10cSrcweir                 aProperties.put( "IsAutoRetrievingEnabled", true );
250*cdf0e10cSrcweir                 aProperties.put( "AutoRetrievingStatement",
251*cdf0e10cSrcweir                     ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CALL IDENTITY()" ) ) );
252*cdf0e10cSrcweir                 aProperties.put( "IgnoreDriverPrivileges", true );
253*cdf0e10cSrcweir 
254*cdf0e10cSrcweir                 // don't want to expose HSQLDB's schema capabilities which exist since 1.8.0RC10
255*cdf0e10cSrcweir                 aProperties.put( "default_schema",
256*cdf0e10cSrcweir                     ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "true" ) ) );
257*cdf0e10cSrcweir 
258*cdf0e10cSrcweir                 // security: permitted Java classes
259*cdf0e10cSrcweir                 NamedValue aPermittedClasses(
260*cdf0e10cSrcweir                     ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "hsqldb.method_class_names" ) ),
261*cdf0e10cSrcweir                     makeAny( lcl_getPermittedJavaMethods_nothrow( m_xFactory ) )
262*cdf0e10cSrcweir                 );
263*cdf0e10cSrcweir                 aProperties.put( "SystemProperties", Sequence< NamedValue >( &aPermittedClasses, 1 ) );
264*cdf0e10cSrcweir 
265*cdf0e10cSrcweir                 const ::rtl::OUString sProperties( RTL_CONSTASCII_USTRINGPARAM( "properties" ) );
266*cdf0e10cSrcweir                 ::rtl::OUString sMessage;
267*cdf0e10cSrcweir                 try
268*cdf0e10cSrcweir                 {
269*cdf0e10cSrcweir                     if ( !bIsNewDatabase && xStorage->isStreamElement(sProperties) )
270*cdf0e10cSrcweir                     {
271*cdf0e10cSrcweir                         Reference<XStream > xStream = xStorage->openStreamElement(sProperties,ElementModes::READ);
272*cdf0e10cSrcweir                         if ( xStream.is() )
273*cdf0e10cSrcweir                         {
274*cdf0e10cSrcweir                             ::std::auto_ptr<SvStream> pStream( ::utl::UcbStreamHelper::CreateStream(xStream) );
275*cdf0e10cSrcweir                             if ( pStream.get() )
276*cdf0e10cSrcweir                             {
277*cdf0e10cSrcweir                                 ByteString sLine;
278*cdf0e10cSrcweir                                 ByteString sVersionString;
279*cdf0e10cSrcweir                                 while ( pStream->ReadLine(sLine) )
280*cdf0e10cSrcweir                                 {
281*cdf0e10cSrcweir                                     if ( sLine.Len() == 0 )
282*cdf0e10cSrcweir                                         continue;
283*cdf0e10cSrcweir                                     const ByteString sIniKey = sLine.GetToken( 0, '=' );
284*cdf0e10cSrcweir                                     const ByteString sValue = sLine.GetToken( 1, '=' );
285*cdf0e10cSrcweir                                     if ( sIniKey.Equals( "hsqldb.compatible_version" ) )
286*cdf0e10cSrcweir                                     {
287*cdf0e10cSrcweir                                         sVersionString = sValue;
288*cdf0e10cSrcweir                                     }
289*cdf0e10cSrcweir                                     else
290*cdf0e10cSrcweir                                     {
291*cdf0e10cSrcweir                                         if  (   sIniKey.Equals( "version" )
292*cdf0e10cSrcweir                                             &&  ( sVersionString.Len() == 0 )
293*cdf0e10cSrcweir                                             )
294*cdf0e10cSrcweir                                         {
295*cdf0e10cSrcweir                                             sVersionString = sValue;
296*cdf0e10cSrcweir                                         }
297*cdf0e10cSrcweir                                     }
298*cdf0e10cSrcweir                                 }
299*cdf0e10cSrcweir                                 if ( sVersionString.Len() )
300*cdf0e10cSrcweir                                 {
301*cdf0e10cSrcweir                                     const sal_Int32 nMajor = sVersionString.GetToken(0,'.').ToInt32();
302*cdf0e10cSrcweir                                     const sal_Int32 nMinor = sVersionString.GetToken(1,'.').ToInt32();
303*cdf0e10cSrcweir                                     const sal_Int32 nMicro = sVersionString.GetToken(2,'.').ToInt32();
304*cdf0e10cSrcweir                                     if (     nMajor > 1
305*cdf0e10cSrcweir                                         || ( nMajor == 1 && nMinor > 8 )
306*cdf0e10cSrcweir                                         || ( nMajor == 1 && nMinor == 8 && nMicro > 0 ) )
307*cdf0e10cSrcweir                                     {
308*cdf0e10cSrcweir                                         ::connectivity::SharedResources aResources;
309*cdf0e10cSrcweir                                         sMessage = aResources.getResourceString(STR_ERROR_NEW_VERSION);
310*cdf0e10cSrcweir                                     }
311*cdf0e10cSrcweir                                 }
312*cdf0e10cSrcweir                             }
313*cdf0e10cSrcweir                         } // if ( xStream.is() )
314*cdf0e10cSrcweir                         ::comphelper::disposeComponent(xStream);
315*cdf0e10cSrcweir                     }
316*cdf0e10cSrcweir                 }
317*cdf0e10cSrcweir                 catch(Exception&)
318*cdf0e10cSrcweir                 {
319*cdf0e10cSrcweir                 }
320*cdf0e10cSrcweir                 if ( sMessage.getLength() )
321*cdf0e10cSrcweir                 {
322*cdf0e10cSrcweir                     ::dbtools::throwGenericSQLException(sMessage ,*this);
323*cdf0e10cSrcweir                 }
324*cdf0e10cSrcweir 
325*cdf0e10cSrcweir                 // readonly?
326*cdf0e10cSrcweir                 Reference<XPropertySet> xProp(xStorage,UNO_QUERY);
327*cdf0e10cSrcweir                 if ( xProp.is() )
328*cdf0e10cSrcweir                 {
329*cdf0e10cSrcweir                     sal_Int32 nMode = 0;
330*cdf0e10cSrcweir                     xProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OpenMode"))) >>= nMode;
331*cdf0e10cSrcweir                     if ( (nMode & ElementModes::WRITE) != ElementModes::WRITE )
332*cdf0e10cSrcweir                     {
333*cdf0e10cSrcweir                         aProperties.put( "readonly", ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "true" ) ) );
334*cdf0e10cSrcweir                     }
335*cdf0e10cSrcweir                 }
336*cdf0e10cSrcweir 
337*cdf0e10cSrcweir                 Sequence< PropertyValue > aConnectionArgs;
338*cdf0e10cSrcweir                 aProperties >>= aConnectionArgs;
339*cdf0e10cSrcweir 
340*cdf0e10cSrcweir                 ::rtl::OUString sConnectURL(RTL_CONSTASCII_USTRINGPARAM("jdbc:hsqldb:"));
341*cdf0e10cSrcweir 
342*cdf0e10cSrcweir                 sConnectURL += sConnPartURL;
343*cdf0e10cSrcweir                 Reference<XConnection> xOrig;
344*cdf0e10cSrcweir                 try
345*cdf0e10cSrcweir                 {
346*cdf0e10cSrcweir                     xOrig = xDriver->connect( sConnectURL, aConnectionArgs );
347*cdf0e10cSrcweir                 }
348*cdf0e10cSrcweir                 catch(const Exception& e)
349*cdf0e10cSrcweir                 {
350*cdf0e10cSrcweir                     StorageContainer::revokeStorage(sKey,NULL);
351*cdf0e10cSrcweir                     (void)e;
352*cdf0e10cSrcweir                     throw;
353*cdf0e10cSrcweir                 }
354*cdf0e10cSrcweir 
355*cdf0e10cSrcweir                 // if the storage is completely empty, then we just created a new HSQLDB
356*cdf0e10cSrcweir                 // In this case, do some initializations.
357*cdf0e10cSrcweir                 if ( bIsNewDatabase && xOrig.is() )
358*cdf0e10cSrcweir                     onConnectedNewDatabase( xOrig );
359*cdf0e10cSrcweir 
360*cdf0e10cSrcweir                 if ( xOrig.is() )
361*cdf0e10cSrcweir                 {
362*cdf0e10cSrcweir                     OMetaConnection* pMetaConnection = NULL;
363*cdf0e10cSrcweir                     // now we have to set the URL to get the correct answer for metadata()->getURL()
364*cdf0e10cSrcweir                     Reference< XUnoTunnel> xTunnel(xOrig,UNO_QUERY);
365*cdf0e10cSrcweir                     if ( xTunnel.is() )
366*cdf0e10cSrcweir                     {
367*cdf0e10cSrcweir                         pMetaConnection = reinterpret_cast<OMetaConnection*>(xTunnel->getSomething( OMetaConnection::getUnoTunnelImplementationId() ));
368*cdf0e10cSrcweir                         if ( pMetaConnection )
369*cdf0e10cSrcweir                             pMetaConnection->setURL(url);
370*cdf0e10cSrcweir                     }
371*cdf0e10cSrcweir 
372*cdf0e10cSrcweir                     Reference<XComponent> xComp(xOrig,UNO_QUERY);
373*cdf0e10cSrcweir                     if ( xComp.is() )
374*cdf0e10cSrcweir                         xComp->addEventListener(this);
375*cdf0e10cSrcweir 
376*cdf0e10cSrcweir                     // we want to close all connections when the office shuts down
377*cdf0e10cSrcweir                     static Reference< XTerminateListener> s_xTerminateListener;
378*cdf0e10cSrcweir                     if( !s_xTerminateListener.is() )
379*cdf0e10cSrcweir                     {
380*cdf0e10cSrcweir                         Reference< XDesktop > xDesktop( m_xFactory->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ), UNO_QUERY );
381*cdf0e10cSrcweir 
382*cdf0e10cSrcweir                         if( xDesktop.is() )
383*cdf0e10cSrcweir                         {
384*cdf0e10cSrcweir                             s_xTerminateListener = new OConnectionController(this);
385*cdf0e10cSrcweir                             xDesktop->addTerminateListener(s_xTerminateListener);
386*cdf0e10cSrcweir                         }
387*cdf0e10cSrcweir                     }
388*cdf0e10cSrcweir                     Reference< XComponent> xIfc = new OHsqlConnection( this, xOrig, m_xFactory );
389*cdf0e10cSrcweir                     xConnection.set(xIfc,UNO_QUERY);
390*cdf0e10cSrcweir                     m_aConnections.push_back(TWeakPair(WeakReferenceHelper(xOrig),TWeakConnectionPair(sKey,TWeakRefPair(WeakReferenceHelper(xConnection),WeakReferenceHelper()))));
391*cdf0e10cSrcweir 
392*cdf0e10cSrcweir                     Reference<XTransactionBroadcaster> xBroad(xStorage,UNO_QUERY);
393*cdf0e10cSrcweir                     if ( xBroad.is() )
394*cdf0e10cSrcweir                     {
395*cdf0e10cSrcweir                         Reference<XTransactionListener> xListener(*this,UNO_QUERY);
396*cdf0e10cSrcweir                         xBroad->addTransactionListener(xListener);
397*cdf0e10cSrcweir                     }
398*cdf0e10cSrcweir                 }
399*cdf0e10cSrcweir             }
400*cdf0e10cSrcweir         }
401*cdf0e10cSrcweir         return xConnection;
402*cdf0e10cSrcweir     }
403*cdf0e10cSrcweir 
404*cdf0e10cSrcweir     //--------------------------------------------------------------------
405*cdf0e10cSrcweir     sal_Bool SAL_CALL ODriverDelegator::acceptsURL( const ::rtl::OUString& url ) throw (SQLException, RuntimeException)
406*cdf0e10cSrcweir     {
407*cdf0e10cSrcweir         sal_Bool bEnabled = sal_False;
408*cdf0e10cSrcweir         OSL_VERIFY_EQUALS( jfw_getEnabled( &bEnabled ), JFW_E_NONE, "error in jfw_getEnabled" );
409*cdf0e10cSrcweir         return bEnabled  && url.compareToAscii("sdbc:embedded:hsqldb",sizeof("sdbc:embedded:hsqldb")) == 0;
410*cdf0e10cSrcweir     }
411*cdf0e10cSrcweir 
412*cdf0e10cSrcweir     //--------------------------------------------------------------------
413*cdf0e10cSrcweir     Sequence< DriverPropertyInfo > SAL_CALL ODriverDelegator::getPropertyInfo( const ::rtl::OUString& url, const Sequence< PropertyValue >& /*info*/ ) throw (SQLException, RuntimeException)
414*cdf0e10cSrcweir     {
415*cdf0e10cSrcweir         if ( !acceptsURL(url) )
416*cdf0e10cSrcweir             return Sequence< DriverPropertyInfo >();
417*cdf0e10cSrcweir         ::std::vector< DriverPropertyInfo > aDriverInfo;
418*cdf0e10cSrcweir         aDriverInfo.push_back(DriverPropertyInfo(
419*cdf0e10cSrcweir                 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Storage"))
420*cdf0e10cSrcweir                 ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Defines the storage where the database will be stored."))
421*cdf0e10cSrcweir                 ,sal_True
422*cdf0e10cSrcweir                 ,::rtl::OUString()
423*cdf0e10cSrcweir                 ,Sequence< ::rtl::OUString >())
424*cdf0e10cSrcweir                 );
425*cdf0e10cSrcweir         aDriverInfo.push_back(DriverPropertyInfo(
426*cdf0e10cSrcweir                 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("URL"))
427*cdf0e10cSrcweir                 ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Defines the url of the data source."))
428*cdf0e10cSrcweir                 ,sal_True
429*cdf0e10cSrcweir                 ,::rtl::OUString()
430*cdf0e10cSrcweir                 ,Sequence< ::rtl::OUString >())
431*cdf0e10cSrcweir                 );
432*cdf0e10cSrcweir         aDriverInfo.push_back(DriverPropertyInfo(
433*cdf0e10cSrcweir                 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AutoRetrievingStatement"))
434*cdf0e10cSrcweir                 ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Defines the statement which will be executed to retrieve auto increment values."))
435*cdf0e10cSrcweir                 ,sal_False
436*cdf0e10cSrcweir                 ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CALL IDENTITY()"))
437*cdf0e10cSrcweir                 ,Sequence< ::rtl::OUString >())
438*cdf0e10cSrcweir                 );
439*cdf0e10cSrcweir         return Sequence< DriverPropertyInfo >(&aDriverInfo[0],aDriverInfo.size());
440*cdf0e10cSrcweir     }
441*cdf0e10cSrcweir 
442*cdf0e10cSrcweir     //--------------------------------------------------------------------
443*cdf0e10cSrcweir     sal_Int32 SAL_CALL ODriverDelegator::getMajorVersion(  ) throw (RuntimeException)
444*cdf0e10cSrcweir     {
445*cdf0e10cSrcweir         return 1;
446*cdf0e10cSrcweir     }
447*cdf0e10cSrcweir 
448*cdf0e10cSrcweir     //--------------------------------------------------------------------
449*cdf0e10cSrcweir     sal_Int32 SAL_CALL ODriverDelegator::getMinorVersion(  ) throw (RuntimeException)
450*cdf0e10cSrcweir     {
451*cdf0e10cSrcweir         return 0;
452*cdf0e10cSrcweir     }
453*cdf0e10cSrcweir 
454*cdf0e10cSrcweir     //--------------------------------------------------------------------
455*cdf0e10cSrcweir     Reference< XTablesSupplier > SAL_CALL ODriverDelegator::getDataDefinitionByConnection( const Reference< XConnection >& connection ) throw (SQLException, RuntimeException)
456*cdf0e10cSrcweir     {
457*cdf0e10cSrcweir         ::osl::MutexGuard aGuard( m_aMutex );
458*cdf0e10cSrcweir         checkDisposed(ODriverDelegator_BASE::rBHelper.bDisposed);
459*cdf0e10cSrcweir 
460*cdf0e10cSrcweir         Reference< XTablesSupplier > xTab;
461*cdf0e10cSrcweir 
462*cdf0e10cSrcweir         TWeakPairVector::iterator aEnd = m_aConnections.end();
463*cdf0e10cSrcweir         for (TWeakPairVector::iterator i = m_aConnections.begin(); aEnd != i; ++i)
464*cdf0e10cSrcweir         {
465*cdf0e10cSrcweir             if ( i->second.second.first.get() == connection.get() )
466*cdf0e10cSrcweir             {
467*cdf0e10cSrcweir                 xTab = Reference< XTablesSupplier >(i->second.second.second.get().get(),UNO_QUERY);
468*cdf0e10cSrcweir                 if ( !xTab.is() )
469*cdf0e10cSrcweir                 {
470*cdf0e10cSrcweir                     xTab = new OHCatalog(connection);
471*cdf0e10cSrcweir                     i->second.second.second = WeakReferenceHelper(xTab);
472*cdf0e10cSrcweir                 }
473*cdf0e10cSrcweir                 break;
474*cdf0e10cSrcweir             }
475*cdf0e10cSrcweir         }
476*cdf0e10cSrcweir 
477*cdf0e10cSrcweir         return xTab;
478*cdf0e10cSrcweir     }
479*cdf0e10cSrcweir 
480*cdf0e10cSrcweir     //--------------------------------------------------------------------
481*cdf0e10cSrcweir     Reference< XTablesSupplier > SAL_CALL ODriverDelegator::getDataDefinitionByURL( const ::rtl::OUString& url, const Sequence< PropertyValue >& info ) throw (SQLException, RuntimeException)
482*cdf0e10cSrcweir     {
483*cdf0e10cSrcweir         if ( ! acceptsURL(url) )
484*cdf0e10cSrcweir         {
485*cdf0e10cSrcweir             ::connectivity::SharedResources aResources;
486*cdf0e10cSrcweir             const ::rtl::OUString sMessage = aResources.getResourceString(STR_URI_SYNTAX_ERROR);
487*cdf0e10cSrcweir             ::dbtools::throwGenericSQLException(sMessage ,*this);
488*cdf0e10cSrcweir         }
489*cdf0e10cSrcweir 
490*cdf0e10cSrcweir         return getDataDefinitionByConnection(connect(url,info));
491*cdf0e10cSrcweir     }
492*cdf0e10cSrcweir 
493*cdf0e10cSrcweir     // XServiceInfo
494*cdf0e10cSrcweir     // --------------------------------------------------------------------------------
495*cdf0e10cSrcweir     //------------------------------------------------------------------------------
496*cdf0e10cSrcweir     rtl::OUString ODriverDelegator::getImplementationName_Static(  ) throw(RuntimeException)
497*cdf0e10cSrcweir     {
498*cdf0e10cSrcweir         return rtl::OUString::createFromAscii("com.sun.star.sdbcx.comp.hsqldb.Driver");
499*cdf0e10cSrcweir     }
500*cdf0e10cSrcweir     //------------------------------------------------------------------------------
501*cdf0e10cSrcweir     Sequence< ::rtl::OUString > ODriverDelegator::getSupportedServiceNames_Static(  ) throw (RuntimeException)
502*cdf0e10cSrcweir     {
503*cdf0e10cSrcweir         Sequence< ::rtl::OUString > aSNS( 2 );
504*cdf0e10cSrcweir         aSNS[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdbc.Driver"));
505*cdf0e10cSrcweir         aSNS[1] = ::rtl::OUString::createFromAscii("com.sun.star.sdbcx.Driver");
506*cdf0e10cSrcweir         return aSNS;
507*cdf0e10cSrcweir     }
508*cdf0e10cSrcweir     //------------------------------------------------------------------
509*cdf0e10cSrcweir     ::rtl::OUString SAL_CALL ODriverDelegator::getImplementationName(  ) throw(RuntimeException)
510*cdf0e10cSrcweir     {
511*cdf0e10cSrcweir         return getImplementationName_Static();
512*cdf0e10cSrcweir     }
513*cdf0e10cSrcweir 
514*cdf0e10cSrcweir     //------------------------------------------------------------------
515*cdf0e10cSrcweir     sal_Bool SAL_CALL ODriverDelegator::supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException)
516*cdf0e10cSrcweir     {
517*cdf0e10cSrcweir         Sequence< ::rtl::OUString > aSupported(getSupportedServiceNames());
518*cdf0e10cSrcweir         const ::rtl::OUString* pSupported = aSupported.getConstArray();
519*cdf0e10cSrcweir         const ::rtl::OUString* pEnd = pSupported + aSupported.getLength();
520*cdf0e10cSrcweir         for (;pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported)
521*cdf0e10cSrcweir             ;
522*cdf0e10cSrcweir 
523*cdf0e10cSrcweir         return pSupported != pEnd;
524*cdf0e10cSrcweir     }
525*cdf0e10cSrcweir     //------------------------------------------------------------------
526*cdf0e10cSrcweir     Sequence< ::rtl::OUString > SAL_CALL ODriverDelegator::getSupportedServiceNames(  ) throw(RuntimeException)
527*cdf0e10cSrcweir     {
528*cdf0e10cSrcweir         return getSupportedServiceNames_Static();
529*cdf0e10cSrcweir     }
530*cdf0e10cSrcweir     //------------------------------------------------------------------
531*cdf0e10cSrcweir     void SAL_CALL ODriverDelegator::createCatalog( const Sequence< PropertyValue >& /*info*/ ) throw (SQLException, ::com::sun::star::container::ElementExistException, RuntimeException)
532*cdf0e10cSrcweir     {
533*cdf0e10cSrcweir         ::dbtools::throwFeatureNotImplementedException( "XCreateCatalog::createCatalog", *this );
534*cdf0e10cSrcweir     }
535*cdf0e10cSrcweir     //------------------------------------------------------------------
536*cdf0e10cSrcweir     void ODriverDelegator::shutdownConnection(const TWeakPairVector::iterator& _aIter )
537*cdf0e10cSrcweir     {
538*cdf0e10cSrcweir         OSL_ENSURE(m_aConnections.end() != _aIter,"Iterator equals .end()");
539*cdf0e10cSrcweir         sal_Bool bLastOne = sal_True;
540*cdf0e10cSrcweir         try
541*cdf0e10cSrcweir         {
542*cdf0e10cSrcweir             Reference<XConnection> _xConnection(_aIter->first.get(),UNO_QUERY);
543*cdf0e10cSrcweir 
544*cdf0e10cSrcweir             if ( _xConnection.is() )
545*cdf0e10cSrcweir             {
546*cdf0e10cSrcweir                 Reference<XStatement> xStmt = _xConnection->createStatement();
547*cdf0e10cSrcweir                 if ( xStmt.is() )
548*cdf0e10cSrcweir                 {
549*cdf0e10cSrcweir                     Reference<XResultSet> xRes(xStmt->executeQuery(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SELECT COUNT(*) FROM INFORMATION_SCHEMA.SYSTEM_SESSIONS WHERE USER_NAME ='SA'"))),UNO_QUERY);
550*cdf0e10cSrcweir                     Reference<XRow> xRow(xRes,UNO_QUERY);
551*cdf0e10cSrcweir                     if ( xRow.is() && xRes->next() )
552*cdf0e10cSrcweir                         bLastOne = xRow->getInt(1) == 1;
553*cdf0e10cSrcweir                     if ( bLastOne )
554*cdf0e10cSrcweir                         xStmt->execute(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SHUTDOWN")));
555*cdf0e10cSrcweir                 }
556*cdf0e10cSrcweir             }
557*cdf0e10cSrcweir         }
558*cdf0e10cSrcweir         catch(Exception&)
559*cdf0e10cSrcweir         {
560*cdf0e10cSrcweir         }
561*cdf0e10cSrcweir         if ( bLastOne )
562*cdf0e10cSrcweir         {
563*cdf0e10cSrcweir             // Reference<XTransactionListener> xListener(*this,UNO_QUERY);
564*cdf0e10cSrcweir             // a shutdown should commit all changes to the db files
565*cdf0e10cSrcweir             StorageContainer::revokeStorage(_aIter->second.first,NULL);
566*cdf0e10cSrcweir         }
567*cdf0e10cSrcweir         if ( !m_bInShutDownConnections )
568*cdf0e10cSrcweir             m_aConnections.erase(_aIter);
569*cdf0e10cSrcweir     }
570*cdf0e10cSrcweir     //------------------------------------------------------------------
571*cdf0e10cSrcweir     void SAL_CALL ODriverDelegator::disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException)
572*cdf0e10cSrcweir     {
573*cdf0e10cSrcweir         ::osl::MutexGuard aGuard(m_aMutex);
574*cdf0e10cSrcweir         Reference<XConnection> xCon(Source.Source,UNO_QUERY);
575*cdf0e10cSrcweir         if ( xCon.is() )
576*cdf0e10cSrcweir         {
577*cdf0e10cSrcweir             TWeakPairVector::iterator i = m_aConnections.begin();
578*cdf0e10cSrcweir             for (; m_aConnections.end() != i; ++i)
579*cdf0e10cSrcweir             {
580*cdf0e10cSrcweir                 if ( i->first.get() == xCon.get() )
581*cdf0e10cSrcweir                 {
582*cdf0e10cSrcweir                     shutdownConnection(i);
583*cdf0e10cSrcweir                     break;
584*cdf0e10cSrcweir                 }
585*cdf0e10cSrcweir             }
586*cdf0e10cSrcweir         }
587*cdf0e10cSrcweir         else
588*cdf0e10cSrcweir         {
589*cdf0e10cSrcweir             Reference< XStorage> xStorage(Source.Source,UNO_QUERY);
590*cdf0e10cSrcweir             if ( xStorage.is() )
591*cdf0e10cSrcweir             {
592*cdf0e10cSrcweir                 ::rtl::OUString sKey = StorageContainer::getRegisteredKey(xStorage);
593*cdf0e10cSrcweir                 TWeakPairVector::iterator i = ::std::find_if(m_aConnections.begin(),m_aConnections.end(),::std::compose1(
594*cdf0e10cSrcweir                                 ::std::bind2nd(::std::equal_to< ::rtl::OUString >(),sKey)
595*cdf0e10cSrcweir                                 ,::std::compose1(::std::select1st<TWeakConnectionPair>(),::std::select2nd< TWeakPair >())));
596*cdf0e10cSrcweir                 if ( i != m_aConnections.end() )
597*cdf0e10cSrcweir                     shutdownConnection(i);
598*cdf0e10cSrcweir             }
599*cdf0e10cSrcweir         }
600*cdf0e10cSrcweir     }
601*cdf0e10cSrcweir     //------------------------------------------------------------------
602*cdf0e10cSrcweir     void ODriverDelegator::shutdownConnections()
603*cdf0e10cSrcweir     {
604*cdf0e10cSrcweir         m_bInShutDownConnections = sal_True;
605*cdf0e10cSrcweir         TWeakPairVector::iterator aEnd = m_aConnections.end();
606*cdf0e10cSrcweir         for (TWeakPairVector::iterator i = m_aConnections.begin(); aEnd != i; ++i)
607*cdf0e10cSrcweir         {
608*cdf0e10cSrcweir             try
609*cdf0e10cSrcweir             {
610*cdf0e10cSrcweir                 Reference<XConnection> xCon(i->first,UNO_QUERY);
611*cdf0e10cSrcweir                 ::comphelper::disposeComponent(xCon);
612*cdf0e10cSrcweir             }
613*cdf0e10cSrcweir             catch(Exception&)
614*cdf0e10cSrcweir             {
615*cdf0e10cSrcweir             }
616*cdf0e10cSrcweir         }
617*cdf0e10cSrcweir         m_aConnections.clear();
618*cdf0e10cSrcweir         m_bInShutDownConnections = sal_True;
619*cdf0e10cSrcweir     }
620*cdf0e10cSrcweir     //------------------------------------------------------------------
621*cdf0e10cSrcweir     void ODriverDelegator::flushConnections()
622*cdf0e10cSrcweir     {
623*cdf0e10cSrcweir         TWeakPairVector::iterator aEnd = m_aConnections.end();
624*cdf0e10cSrcweir         for (TWeakPairVector::iterator i = m_aConnections.begin(); aEnd != i; ++i)
625*cdf0e10cSrcweir         {
626*cdf0e10cSrcweir             try
627*cdf0e10cSrcweir             {
628*cdf0e10cSrcweir                 Reference<XFlushable> xCon(i->second.second.first.get(),UNO_QUERY);
629*cdf0e10cSrcweir                 xCon->flush();
630*cdf0e10cSrcweir             }
631*cdf0e10cSrcweir             catch(Exception&)
632*cdf0e10cSrcweir             {
633*cdf0e10cSrcweir             }
634*cdf0e10cSrcweir         }
635*cdf0e10cSrcweir     }
636*cdf0e10cSrcweir     //------------------------------------------------------------------
637*cdf0e10cSrcweir     void SAL_CALL ODriverDelegator::preCommit( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
638*cdf0e10cSrcweir     {
639*cdf0e10cSrcweir         ::osl::MutexGuard aGuard(m_aMutex);
640*cdf0e10cSrcweir 
641*cdf0e10cSrcweir         Reference< XStorage> xStorage(aEvent.Source,UNO_QUERY);
642*cdf0e10cSrcweir         ::rtl::OUString sKey = StorageContainer::getRegisteredKey(xStorage);
643*cdf0e10cSrcweir         if ( sKey.getLength() )
644*cdf0e10cSrcweir         {
645*cdf0e10cSrcweir             TWeakPairVector::iterator i = ::std::find_if(m_aConnections.begin(),m_aConnections.end(),::std::compose1(
646*cdf0e10cSrcweir                             ::std::bind2nd(::std::equal_to< ::rtl::OUString >(),sKey)
647*cdf0e10cSrcweir                             ,::std::compose1(::std::select1st<TWeakConnectionPair>(),::std::select2nd< TWeakPair >())));
648*cdf0e10cSrcweir             OSL_ENSURE( i != m_aConnections.end(), "ODriverDelegator::preCommit: they're committing a storage which I do not know!" );
649*cdf0e10cSrcweir             if ( i != m_aConnections.end() )
650*cdf0e10cSrcweir             {
651*cdf0e10cSrcweir                 try
652*cdf0e10cSrcweir                 {
653*cdf0e10cSrcweir                     Reference<XConnection> xConnection(i->first,UNO_QUERY);
654*cdf0e10cSrcweir                     if ( xConnection.is() )
655*cdf0e10cSrcweir                     {
656*cdf0e10cSrcweir                         Reference< XStatement> xStmt = xConnection->createStatement();
657*cdf0e10cSrcweir                         OSL_ENSURE( xStmt.is(), "ODriverDelegator::preCommit: no statement!" );
658*cdf0e10cSrcweir                         if ( xStmt.is() )
659*cdf0e10cSrcweir                             xStmt->execute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SET WRITE_DELAY 0" ) ) );
660*cdf0e10cSrcweir 
661*cdf0e10cSrcweir                         sal_Bool bPreviousAutoCommit = xConnection->getAutoCommit();
662*cdf0e10cSrcweir                         xConnection->setAutoCommit( sal_False );
663*cdf0e10cSrcweir                         xConnection->commit();
664*cdf0e10cSrcweir                         xConnection->setAutoCommit( bPreviousAutoCommit );
665*cdf0e10cSrcweir 
666*cdf0e10cSrcweir                         if ( xStmt.is() )
667*cdf0e10cSrcweir                             xStmt->execute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SET WRITE_DELAY 60" ) ) );
668*cdf0e10cSrcweir                     }
669*cdf0e10cSrcweir                 }
670*cdf0e10cSrcweir                 catch(Exception&)
671*cdf0e10cSrcweir                 {
672*cdf0e10cSrcweir                     OSL_ENSURE( false, "ODriverDelegator::preCommit: caught an exception!" );
673*cdf0e10cSrcweir                 }
674*cdf0e10cSrcweir             }
675*cdf0e10cSrcweir         }
676*cdf0e10cSrcweir     }
677*cdf0e10cSrcweir     //------------------------------------------------------------------
678*cdf0e10cSrcweir     void SAL_CALL ODriverDelegator::commited( const ::com::sun::star::lang::EventObject& /*aEvent*/ ) throw (::com::sun::star::uno::RuntimeException)
679*cdf0e10cSrcweir     {
680*cdf0e10cSrcweir     }
681*cdf0e10cSrcweir     //------------------------------------------------------------------
682*cdf0e10cSrcweir     void SAL_CALL ODriverDelegator::preRevert( const ::com::sun::star::lang::EventObject& /*aEvent*/ ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
683*cdf0e10cSrcweir     {
684*cdf0e10cSrcweir     }
685*cdf0e10cSrcweir     //------------------------------------------------------------------
686*cdf0e10cSrcweir     void SAL_CALL ODriverDelegator::reverted( const ::com::sun::star::lang::EventObject& /*aEvent*/ ) throw (::com::sun::star::uno::RuntimeException)
687*cdf0e10cSrcweir     {
688*cdf0e10cSrcweir     }
689*cdf0e10cSrcweir     //------------------------------------------------------------------
690*cdf0e10cSrcweir     namespace
691*cdf0e10cSrcweir     {
692*cdf0e10cSrcweir         //..............................................................
693*cdf0e10cSrcweir         const sal_Char* lcl_getCollationForLocale( const ::rtl::OUString& _rLocaleString, bool _bAcceptCountryMismatch = false )
694*cdf0e10cSrcweir         {
695*cdf0e10cSrcweir             static const sal_Char* pTranslations[] =
696*cdf0e10cSrcweir             {
697*cdf0e10cSrcweir                 "af-ZA", "Afrikaans",
698*cdf0e10cSrcweir                 "am-ET", "Amharic",
699*cdf0e10cSrcweir                 "ar", "Arabic",
700*cdf0e10cSrcweir                 "as-IN", "Assamese",
701*cdf0e10cSrcweir                 "az-AZ", "Azerbaijani_Latin",
702*cdf0e10cSrcweir                 "az-cyrillic", "Azerbaijani_Cyrillic",
703*cdf0e10cSrcweir                 "be-BY", "Belarusian",
704*cdf0e10cSrcweir                 "bg-BG", "Bulgarian",
705*cdf0e10cSrcweir                 "bn-IN", "Bengali",
706*cdf0e10cSrcweir                 "bo-CN", "Tibetan",
707*cdf0e10cSrcweir                 "bs-BA", "Bosnian",
708*cdf0e10cSrcweir                 "ca-ES", "Catalan",
709*cdf0e10cSrcweir                 "cs-CZ", "Czech",
710*cdf0e10cSrcweir                 "cy-GB", "Welsh",
711*cdf0e10cSrcweir                 "da-DK", "Danish",
712*cdf0e10cSrcweir                 "de-DE", "German",
713*cdf0e10cSrcweir                 "el-GR", "Greek",
714*cdf0e10cSrcweir                 "en-US", "Latin1_General",
715*cdf0e10cSrcweir                 "es-ES", "Spanish",
716*cdf0e10cSrcweir                 "et-EE", "Estonian",
717*cdf0e10cSrcweir                 "eu", "Basque",
718*cdf0e10cSrcweir                 "fi-FI", "Finnish",
719*cdf0e10cSrcweir                 "fr-FR", "French",
720*cdf0e10cSrcweir                 "gn-PY", "Guarani",
721*cdf0e10cSrcweir                 "gu-IN", "Gujarati",
722*cdf0e10cSrcweir                 "ha-NG", "Hausa",
723*cdf0e10cSrcweir                 "he-IL", "Hebrew",
724*cdf0e10cSrcweir                 "hi-IN", "Hindi",
725*cdf0e10cSrcweir                 "hr-HR", "Croatian",
726*cdf0e10cSrcweir                 "hu-HU", "Hungarian",
727*cdf0e10cSrcweir                 "hy-AM", "Armenian",
728*cdf0e10cSrcweir                 "id-ID", "Indonesian",
729*cdf0e10cSrcweir                 "ig-NG", "Igbo",
730*cdf0e10cSrcweir                 "is-IS", "Icelandic",
731*cdf0e10cSrcweir                 "it-IT", "Italian",
732*cdf0e10cSrcweir                 "iu-CA", "Inuktitut",
733*cdf0e10cSrcweir                 "ja-JP", "Japanese",
734*cdf0e10cSrcweir                 "ka-GE", "Georgian",
735*cdf0e10cSrcweir                 "kk-KZ", "Kazakh",
736*cdf0e10cSrcweir                 "km-KH", "Khmer",
737*cdf0e10cSrcweir                 "kn-IN", "Kannada",
738*cdf0e10cSrcweir                 "ko-KR", "Korean",
739*cdf0e10cSrcweir                 "kok-IN", "Konkani",
740*cdf0e10cSrcweir                 "ks", "Kashmiri",
741*cdf0e10cSrcweir                 "ky-KG", "Kirghiz",
742*cdf0e10cSrcweir                 "lo-LA", "Lao",
743*cdf0e10cSrcweir                 "lt-LT", "Lithuanian",
744*cdf0e10cSrcweir                 "lv-LV", "Latvian",
745*cdf0e10cSrcweir                 "mi-NZ", "Maori",
746*cdf0e10cSrcweir                 "mk-MK", "Macedonian",
747*cdf0e10cSrcweir                 "ml-IN", "Malayalam",
748*cdf0e10cSrcweir                 "mn-MN", "Mongolian",
749*cdf0e10cSrcweir                 "mni-IN", "Manipuri",
750*cdf0e10cSrcweir                 "mr-IN", "Marathi",
751*cdf0e10cSrcweir                 "ms-MY", "Malay",
752*cdf0e10cSrcweir                 "mt-MT", "Maltese",
753*cdf0e10cSrcweir                 "my-MM", "Burmese",
754*cdf0e10cSrcweir                 "nb-NO", "Danish_Norwegian",
755*cdf0e10cSrcweir                 "ne-NP", "Nepali",
756*cdf0e10cSrcweir                 "nl-NL", "Dutch",
757*cdf0e10cSrcweir                 "nn-NO", "Norwegian",
758*cdf0e10cSrcweir                 "or-IN", "Oriya",
759*cdf0e10cSrcweir                 "pa-IN", "Punjabi",
760*cdf0e10cSrcweir                 "pl-PL", "Polish",
761*cdf0e10cSrcweir                 "ps-AF", "Pashto",
762*cdf0e10cSrcweir                 "pt-PT", "Portuguese",
763*cdf0e10cSrcweir                 "ro-RO", "Romanian",
764*cdf0e10cSrcweir                 "ru-RU", "Russian",
765*cdf0e10cSrcweir                 "sa-IN", "Sanskrit",
766*cdf0e10cSrcweir                 "sd-IN", "Sindhi",
767*cdf0e10cSrcweir                 "sk-SK", "Slovak",
768*cdf0e10cSrcweir                 "sl-SI", "Slovenian",
769*cdf0e10cSrcweir                 "so-SO", "Somali",
770*cdf0e10cSrcweir                 "sq-AL", "Albanian",
771*cdf0e10cSrcweir                 "sr-YU", "Serbian_Cyrillic",
772*cdf0e10cSrcweir                 "sv-SE", "Swedish",
773*cdf0e10cSrcweir                 "sw-KE", "Swahili",
774*cdf0e10cSrcweir                 "ta-IN", "Tamil",
775*cdf0e10cSrcweir                 "te-IN", "Telugu",
776*cdf0e10cSrcweir                 "tg-TJ", "Tajik",
777*cdf0e10cSrcweir                 "th-TH", "Thai",
778*cdf0e10cSrcweir                 "tk-TM", "Turkmen",
779*cdf0e10cSrcweir                 "tn-BW", "Tswana",
780*cdf0e10cSrcweir                 "tr-TR", "Turkish",
781*cdf0e10cSrcweir                 "tt-RU", "Tatar",
782*cdf0e10cSrcweir                 "uk-UA", "Ukrainian",
783*cdf0e10cSrcweir                 "ur-PK", "Urdu",
784*cdf0e10cSrcweir                 "uz-UZ", "Uzbek_Latin",
785*cdf0e10cSrcweir                 "ven-ZA", "Venda",
786*cdf0e10cSrcweir                 "vi-VN", "Vietnamese",
787*cdf0e10cSrcweir                 "yo-NG", "Yoruba",
788*cdf0e10cSrcweir                 "zh-CN", "Chinese",
789*cdf0e10cSrcweir                 "zu-ZA", "Zulu",
790*cdf0e10cSrcweir                 NULL, NULL
791*cdf0e10cSrcweir             };
792*cdf0e10cSrcweir 
793*cdf0e10cSrcweir             ::rtl::OUString sLocaleString( _rLocaleString );
794*cdf0e10cSrcweir             sal_Char nCompareTermination = 0;
795*cdf0e10cSrcweir 
796*cdf0e10cSrcweir             if ( _bAcceptCountryMismatch )
797*cdf0e10cSrcweir             {
798*cdf0e10cSrcweir                 // strip the country part from the compare string
799*cdf0e10cSrcweir                 sal_Int32 nCountrySep = sLocaleString.indexOf( '-' );
800*cdf0e10cSrcweir                 if ( nCountrySep > -1 )
801*cdf0e10cSrcweir                     sLocaleString = sLocaleString.copy( 0, nCountrySep );
802*cdf0e10cSrcweir 
803*cdf0e10cSrcweir                 // the entries in the translation table are compared until the
804*cdf0e10cSrcweir                 // - character only, not until the terminating 0
805*cdf0e10cSrcweir                 nCompareTermination = '-';
806*cdf0e10cSrcweir             }
807*cdf0e10cSrcweir 
808*cdf0e10cSrcweir             const sal_Char** pLookup = pTranslations;
809*cdf0e10cSrcweir             for ( ; *pLookup; pLookup +=2 )
810*cdf0e10cSrcweir             {
811*cdf0e10cSrcweir                 sal_Int32 nCompareUntil = 0;
812*cdf0e10cSrcweir                 while ( (*pLookup)[ nCompareUntil ] != nCompareTermination && (*pLookup)[ nCompareUntil ] != 0 )
813*cdf0e10cSrcweir                     ++nCompareUntil;
814*cdf0e10cSrcweir 
815*cdf0e10cSrcweir                 if ( sLocaleString.equalsAsciiL( *pLookup, nCompareUntil ) )
816*cdf0e10cSrcweir                     return *( pLookup + 1 );
817*cdf0e10cSrcweir             }
818*cdf0e10cSrcweir 
819*cdf0e10cSrcweir             if ( !_bAcceptCountryMismatch )
820*cdf0e10cSrcweir                 // second round, this time without matching the country
821*cdf0e10cSrcweir                 return lcl_getCollationForLocale( _rLocaleString, true );
822*cdf0e10cSrcweir 
823*cdf0e10cSrcweir             OSL_ENSURE( false, "lcl_getCollationForLocale: unknown locale string, falling back to Latin1_General!" );
824*cdf0e10cSrcweir             return "Latin1_General";
825*cdf0e10cSrcweir         }
826*cdf0e10cSrcweir 
827*cdf0e10cSrcweir         //..............................................................
828*cdf0e10cSrcweir         ::rtl::OUString lcl_getSystemLocale( const Reference< XMultiServiceFactory >& _rxORB )
829*cdf0e10cSrcweir         {
830*cdf0e10cSrcweir             ::rtl::OUString sLocaleString = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "en-US" ) );
831*cdf0e10cSrcweir             try
832*cdf0e10cSrcweir             {
833*cdf0e10cSrcweir                 //.........................................................
834*cdf0e10cSrcweir                 Reference< XMultiServiceFactory > xConfigProvider(
835*cdf0e10cSrcweir                     _rxORB->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.configuration.ConfigurationProvider" ) ),
836*cdf0e10cSrcweir                     UNO_QUERY
837*cdf0e10cSrcweir                 );
838*cdf0e10cSrcweir                 OSL_ENSURE( xConfigProvider.is(), "lcl_getSystemLocale: could not create the config provider!" );
839*cdf0e10cSrcweir 
840*cdf0e10cSrcweir                 if ( !xConfigProvider.is() )
841*cdf0e10cSrcweir                     return sLocaleString;
842*cdf0e10cSrcweir 
843*cdf0e10cSrcweir                 //.........................................................
844*cdf0e10cSrcweir                 // arguments for creating the config access
845*cdf0e10cSrcweir                 Sequence< Any > aArguments(2);
846*cdf0e10cSrcweir                 // the path to the node to open
847*cdf0e10cSrcweir                 ::rtl::OUString sNodePath = ::rtl::OUString::createFromAscii ("/org.openoffice.Setup/L10N" );
848*cdf0e10cSrcweir                 aArguments[0] <<= PropertyValue( ::rtl::OUString::createFromAscii( "nodepath"), 0,
849*cdf0e10cSrcweir                     makeAny( sNodePath ), PropertyState_DIRECT_VALUE
850*cdf0e10cSrcweir                 );
851*cdf0e10cSrcweir                 // the depth: -1 means unlimited
852*cdf0e10cSrcweir                 aArguments[1] <<= PropertyValue(
853*cdf0e10cSrcweir                     ::rtl::OUString::createFromAscii( "depth"), 0,
854*cdf0e10cSrcweir                     makeAny( (sal_Int32)-1 ), PropertyState_DIRECT_VALUE
855*cdf0e10cSrcweir                 );
856*cdf0e10cSrcweir 
857*cdf0e10cSrcweir                 //.........................................................
858*cdf0e10cSrcweir                 // create the access
859*cdf0e10cSrcweir                 Reference< XPropertySet > xNode(
860*cdf0e10cSrcweir                     xConfigProvider->createInstanceWithArguments(
861*cdf0e10cSrcweir                         ::rtl::OUString::createFromAscii( "com.sun.star.configuration.ConfigurationAccess" ),
862*cdf0e10cSrcweir                         aArguments ),
863*cdf0e10cSrcweir                     UNO_QUERY );
864*cdf0e10cSrcweir                 OSL_ENSURE( xNode.is(), "lcl_getSystemLocale: invalid access returned (should throw an exception instead)!" );
865*cdf0e10cSrcweir 
866*cdf0e10cSrcweir                 //.........................................................
867*cdf0e10cSrcweir                 // ask for the system locale setting
868*cdf0e10cSrcweir                 if ( xNode.is() )
869*cdf0e10cSrcweir                     xNode->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooSetupSystemLocale" ) ) ) >>= sLocaleString;
870*cdf0e10cSrcweir             }
871*cdf0e10cSrcweir             catch( const Exception& )
872*cdf0e10cSrcweir             {
873*cdf0e10cSrcweir                 OSL_ENSURE( sal_False, "lcl_getSystemLocale: caught an exception!" );
874*cdf0e10cSrcweir             }
875*cdf0e10cSrcweir             if ( !sLocaleString.getLength() )
876*cdf0e10cSrcweir             {
877*cdf0e10cSrcweir                 rtl_Locale* pProcessLocale = NULL;
878*cdf0e10cSrcweir                 osl_getProcessLocale( &pProcessLocale );
879*cdf0e10cSrcweir 
880*cdf0e10cSrcweir                 ::rtl::OUStringBuffer aProcLocale;
881*cdf0e10cSrcweir                 aProcLocale.append( pProcessLocale->Language->buffer, pProcessLocale->Language->length );
882*cdf0e10cSrcweir                 if ( pProcessLocale->Country->length )
883*cdf0e10cSrcweir                 {
884*cdf0e10cSrcweir                     aProcLocale.appendAscii( "-" );
885*cdf0e10cSrcweir                     aProcLocale.append( pProcessLocale->Country->buffer, pProcessLocale->Country->length );
886*cdf0e10cSrcweir                 }
887*cdf0e10cSrcweir                 sLocaleString = aProcLocale.makeStringAndClear();
888*cdf0e10cSrcweir             }
889*cdf0e10cSrcweir             return sLocaleString;
890*cdf0e10cSrcweir         }
891*cdf0e10cSrcweir     }
892*cdf0e10cSrcweir     //------------------------------------------------------------------
893*cdf0e10cSrcweir     void ODriverDelegator::onConnectedNewDatabase( const Reference< XConnection >& _rxConnection )
894*cdf0e10cSrcweir     {
895*cdf0e10cSrcweir         try
896*cdf0e10cSrcweir         {
897*cdf0e10cSrcweir             Reference< XStatement > xStatement = _rxConnection->createStatement();
898*cdf0e10cSrcweir             OSL_ENSURE( xStatement.is(), "ODriverDelegator::onConnectedNewDatabase: could not create a statement!" );
899*cdf0e10cSrcweir             if ( xStatement.is() )
900*cdf0e10cSrcweir             {
901*cdf0e10cSrcweir                 ::rtl::OUStringBuffer aStatement;
902*cdf0e10cSrcweir                 aStatement.appendAscii( "SET DATABASE COLLATION \"" );
903*cdf0e10cSrcweir                 aStatement.appendAscii( lcl_getCollationForLocale( lcl_getSystemLocale( m_xFactory ) ) );
904*cdf0e10cSrcweir                 aStatement.appendAscii( "\"" );
905*cdf0e10cSrcweir 
906*cdf0e10cSrcweir                 xStatement->execute( aStatement.makeStringAndClear() );
907*cdf0e10cSrcweir             }
908*cdf0e10cSrcweir         }
909*cdf0e10cSrcweir         catch( const Exception& )
910*cdf0e10cSrcweir         {
911*cdf0e10cSrcweir             OSL_ENSURE( sal_False, "ODriverDelegator::onConnectedNewDatabase: caught an exception!" );
912*cdf0e10cSrcweir         }
913*cdf0e10cSrcweir     }
914*cdf0e10cSrcweir 
915*cdf0e10cSrcweir     //------------------------------------------------------------------
916*cdf0e10cSrcweir     //------------------------------------------------------------------
917*cdf0e10cSrcweir //........................................................................
918*cdf0e10cSrcweir }   // namespace connectivity
919*cdf0e10cSrcweir //........................................................................
920*cdf0e10cSrcweir 
921