1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sw.hxx"
30 #include <com/sun/star/sdbc/XConnection.hpp>
31 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
32 #include <com/sun/star/sdbc/XDataSource.hpp>
33 #include <com/sun/star/sdb/SQLContext.hpp>
34 #include <swdbtoolsclient.hxx>
35 #include <osl/diagnose.h>
36 #include <tools/solar.h>
37 
38 //........................................................................
39 
40 using namespace ::connectivity::simple;
41 using namespace ::com::sun::star;
42 using namespace ::com::sun::star::sdbc;
43 using namespace ::com::sun::star::lang;
44 using namespace ::com::sun::star::util;
45 using namespace ::com::sun::star::uno;
46 using namespace ::com::sun::star::beans;
47 using namespace ::com::sun::star::sdb;
48 
49 //====================================================================
50 //= SwDbtoolsClient
51 //====================================================================
52 namespace
53 {
54 	// -----------------------------------------------------------------------------
55 	// this namespace contains access to all static members of the class SwDbtoolsClient
56 	// to make the initialize of the dll a little bit faster
57 	// -----------------------------------------------------------------------------
58 	::osl::Mutex& getDbtoolsClientMutex()
59 	{
60 		static  ::osl::Mutex aMutex;
61 		return aMutex;
62 	}
63 	// -----------------------------------------------------------------------------
64 	sal_Int32& getDbToolsClientClients()
65 	{
66 		static  sal_Int32 nClients = 0;
67 		return nClients;
68 	}
69 	// -----------------------------------------------------------------------------
70 	oslModule& getDbToolsClientModule()
71 	{
72 		static oslModule hDbtoolsModule = NULL;
73 		return hDbtoolsModule;
74 	}
75 	// -----------------------------------------------------------------------------
76 	createDataAccessToolsFactoryFunction& getDbToolsClientFactoryFunction()
77 	{
78 		static createDataAccessToolsFactoryFunction pFactoryCreationFunc = NULL;
79 		return pFactoryCreationFunc;
80 	}
81 	// -----------------------------------------------------------------------------
82 }
83 // -----------------------------------------------------------------------------
84 SwDbtoolsClient::SwDbtoolsClient()
85 {
86 }
87 
88 //--------------------------------------------------------------------
89 SwDbtoolsClient::~SwDbtoolsClient()
90 {
91     if(m_xDataAccessFactory.is())
92     {
93         // clear the factory _before_ revoking the client
94         // (the revocation may unload the DBT lib)
95         m_xDataAccessFactory = NULL;
96         // revoke the client
97         revokeClient();
98     }
99 }
100 
101 //--------------------------------------------------------------------
102 extern "C" { static void SAL_CALL thisModule() {} }
103 
104 void SwDbtoolsClient::registerClient()
105 {
106     ::osl::MutexGuard aGuard(getDbtoolsClientMutex());
107     if (1 == ++getDbToolsClientClients())
108     {
109         OSL_ENSURE(NULL == getDbToolsClientModule(), "SwDbtoolsClient::registerClient: inconsistence: already have a module!");
110         OSL_ENSURE(NULL == getDbToolsClientFactoryFunction(), "SwDbtoolsClient::registerClient: inconsistence: already have a factory function!");
111 
112         const ::rtl::OUString sModuleName = ::rtl::OUString::createFromAscii(
113             SVLIBRARY( "dbtools" )
114         );
115 
116         // load the dbtools library
117         getDbToolsClientModule() = osl_loadModuleRelative(
118             &thisModule, sModuleName.pData, 0);
119         OSL_ENSURE(NULL != getDbToolsClientModule(), "SwDbtoolsClient::registerClient: could not load the dbtools library!");
120         if (NULL != getDbToolsClientModule())
121         {
122             // get the symbol for the method creating the factory
123             const ::rtl::OUString sFactoryCreationFunc = ::rtl::OUString::createFromAscii("createDataAccessToolsFactory");
124             //  reinterpret_cast<createDataAccessToolsFactoryFunction> removed for gcc permissive
125             getDbToolsClientFactoryFunction() = reinterpret_cast< createDataAccessToolsFactoryFunction >(
126                 osl_getFunctionSymbol(getDbToolsClientModule(), sFactoryCreationFunc.pData));
127 
128             if (NULL == getDbToolsClientFactoryFunction())
129             {   // did not find the symbol
130                 OSL_ENSURE(sal_False, "SwDbtoolsClient::registerClient: could not find the symbol for creating the factory!");
131                 osl_unloadModule(getDbToolsClientModule());
132                 getDbToolsClientModule() = NULL;
133             }
134         }
135     }
136 }
137 
138 //--------------------------------------------------------------------
139 void SwDbtoolsClient::revokeClient()
140 {
141     ::osl::MutexGuard aGuard(getDbtoolsClientMutex());
142     if (0 == --getDbToolsClientClients())
143     {
144         getDbToolsClientFactoryFunction() = NULL;
145         if (getDbToolsClientModule())
146             osl_unloadModule(getDbToolsClientModule());
147         getDbToolsClientModule() = NULL;
148     }
149 }
150 /* -----------------------------30.08.2001 14:58------------------------------
151 
152  ---------------------------------------------------------------------------*/
153 void SwDbtoolsClient::getFactory()
154 {
155     if(!m_xDataAccessFactory.is())
156     {
157         registerClient();
158         if(getDbToolsClientFactoryFunction())
159 		{	// loading the lib succeeded
160             void* pUntypedFactory = (*getDbToolsClientFactoryFunction())();
161 			IDataAccessToolsFactory* pDBTFactory = static_cast<IDataAccessToolsFactory*>(pUntypedFactory);
162             OSL_ENSURE(pDBTFactory, "SwDbtoolsClient::SwDbtoolsClient: no factory returned!");
163 			if (pDBTFactory)
164 			{
165 				m_xDataAccessFactory = pDBTFactory;
166 				// by definition, the factory was aquired once
167 				m_xDataAccessFactory->release();
168 			}
169 		}
170     }
171 }
172 /* -----------------------------30.08.2001 11:32------------------------------
173 
174  ---------------------------------------------------------------------------*/
175 ::rtl::Reference< ::connectivity::simple::IDataAccessTools >
176     SwDbtoolsClient::getDataAccessTools()
177 {
178     if(!m_xDataAccessTools.is())
179     {
180         getFactory();
181         if(m_xDataAccessFactory.is())
182             m_xDataAccessTools = m_xDataAccessFactory->getDataAccessTools();
183     }
184     return m_xDataAccessTools;
185 }
186 /* -----------------------------30.08.2001 12:40------------------------------
187 
188  ---------------------------------------------------------------------------*/
189 ::rtl::Reference< ::connectivity::simple::IDataAccessTypeConversion >
190     SwDbtoolsClient::getAccessTypeConversion()
191 {
192     if(!m_xAccessTypeConversion.is())
193     {
194         getFactory();
195         if(m_xDataAccessFactory.is())
196             m_xAccessTypeConversion = m_xDataAccessFactory->getTypeConversionHelper();
197     }
198     return m_xAccessTypeConversion;
199 }
200 
201 /* -----------------------------30.08.2001 11:37------------------------------
202 
203  ---------------------------------------------------------------------------*/
204 Reference< XDataSource > SwDbtoolsClient::getDataSource(
205         const ::rtl::OUString& rRegisteredName,
206         const Reference< XMultiServiceFactory>& xFactory
207             )
208 {
209     Reference< XDataSource > xRet;
210     ::rtl::Reference< ::connectivity::simple::IDataAccessTools >    xAccess = getDataAccessTools();
211     if(xAccess.is())
212         xRet = xAccess->getDataSource(rRegisteredName, xFactory);
213     return xRet;
214 }
215 /* -----------------------------30.08.2001 12:06------------------------------
216 
217  ---------------------------------------------------------------------------*/
218 sal_Int32 SwDbtoolsClient::getDefaultNumberFormat(
219         const Reference< XPropertySet >& rxColumn,
220         const Reference< XNumberFormatTypes >& rxTypes,
221         const Locale& rLocale
222             )
223 {
224     sal_Int32 nRet = -1;
225     ::rtl::Reference< ::connectivity::simple::IDataAccessTools >    xAccess = getDataAccessTools();
226     if(xAccess.is())
227         nRet = xAccess->getDefaultNumberFormat( rxColumn, rxTypes, rLocale);
228     return nRet;
229 }
230 /* -----------------------------30.08.2001 12:38------------------------------
231 
232  ---------------------------------------------------------------------------*/
233 ::rtl::OUString SwDbtoolsClient::getFormattedValue(
234         const uno::Reference< beans::XPropertySet>& _rxColumn,
235         const uno::Reference< util::XNumberFormatter>& _rxFormatter,
236         const lang::Locale& _rLocale,
237         const util::Date& _rNullDate
238             )
239 
240 {
241     ::rtl::Reference< ::connectivity::simple::IDataAccessTypeConversion > xConversion =
242                     getAccessTypeConversion();
243     rtl::OUString sRet;
244     if(xConversion.is())
245         sRet = xConversion->getFormattedValue(_rxColumn, _rxFormatter, _rLocale, _rNullDate);
246     return sRet;
247 }
248 
249