LibreOffice Module dbaccess (master) 1
dbloader.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <strings.hxx>
21#include <UITools.hxx>
22
23#include <com/sun/star/container/XChild.hpp>
24#include <com/sun/star/frame/XController2.hpp>
25#include <com/sun/star/frame/XFrame.hpp>
26#include <com/sun/star/frame/XFrameLoader.hpp>
27#include <com/sun/star/frame/XLoadEventListener.hpp>
28#include <com/sun/star/lang/XInitialization.hpp>
29#include <com/sun/star/lang/XServiceInfo.hpp>
30#include <com/sun/star/sdb/ReportDesign.hpp>
31#include <com/sun/star/sdbc/XConnection.hpp>
32#include <com/sun/star/frame/XModule.hpp>
33
34#include <com/sun/star/sdbc/XDataSource.hpp>
36#include <comphelper/types.hxx>
40#include <tools/urlobj.hxx>
41#include <unotools/fcm.hxx>
42#include <vcl/svapp.hxx>
43
44using namespace ::com::sun::star;
45using namespace ::com::sun::star::uno;
46using namespace ::com::sun::star::frame;
47using namespace ::com::sun::star::beans;
48using namespace ::com::sun::star::sdb;
49using namespace ::com::sun::star::sdbc;
50using namespace ::com::sun::star::container;
51using namespace ::com::sun::star::lang;
52using namespace dbaui;
53
54namespace {
55
56class DBContentLoader : public ::cppu::WeakImplHelper< XFrameLoader, XServiceInfo>
57{
58private:
62public:
63 explicit DBContentLoader(const Reference< XComponentContext >&);
64
65 // XServiceInfo
66 OUString SAL_CALL getImplementationName() override;
67 sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override;
69
70 // XLoader
71 virtual void SAL_CALL load( const Reference< XFrame > & _rFrame, const OUString& _rURL,
72 const Sequence< PropertyValue >& _rArgs,
73 const Reference< XLoadEventListener > & _rListener) override;
74 virtual void SAL_CALL cancel() override;
75};
76
77}
78
79DBContentLoader::DBContentLoader(const Reference< XComponentContext >& _rxContext)
80 :m_xContext(_rxContext)
81{
82
83}
84
85extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
87 css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& )
88{
89 return cppu::acquire(new DBContentLoader(context));
90}
91
92// XServiceInfo
93OUString SAL_CALL DBContentLoader::getImplementationName()
94{
95 return "org.openoffice.comp.dbu.DBContentLoader";
96}
97
98// XServiceInfo
99sal_Bool SAL_CALL DBContentLoader::supportsService(const OUString& ServiceName)
100{
101 return cppu::supportsService(this, ServiceName);
102}
103
104// XServiceInfo
105Sequence< OUString > SAL_CALL DBContentLoader::getSupportedServiceNames()
106{
107 return { "com.sun.star.frame.FrameLoader", "com.sun.star.sdb.ContentLoader" };
108}
109
110void SAL_CALL DBContentLoader::load(const Reference< XFrame > & rFrame, const OUString& rURL,
111 const Sequence< PropertyValue >& rArgs,
112 const Reference< XLoadEventListener > & rListener)
113{
114 m_xListener = rListener;
115 m_aArgs = rArgs;
116
117 static constexpr struct ServiceNameToImplName
118 {
119 rtl::OUStringConstExpr sServiceName;
120 const char* pAsciiImplementationName;
121 } aImplementations[] = {
122 { URL_COMPONENT_FORMGRIDVIEW, "org.openoffice.comp.dbu.OFormGridView" },
123 { URL_COMPONENT_DATASOURCEBROWSER, "org.openoffice.comp.dbu.ODatasourceBrowser" },
124 { URL_COMPONENT_QUERYDESIGN, "org.openoffice.comp.dbu.OQueryDesign" },
125 { URL_COMPONENT_TABLEDESIGN, "org.openoffice.comp.dbu.OTableDesign" },
126 { URL_COMPONENT_RELATIONDESIGN, "org.openoffice.comp.dbu.ORelationDesign" },
127 { URL_COMPONENT_VIEWDESIGN, "org.openoffice.comp.dbu.OViewDesign" }
128 };
129
130 INetURLObject aParser( rURL );
132
133 const OUString sComponentURL( aParser.GetMainURL( INetURLObject::DecodeMechanism::ToIUri ) );
134 for (const ServiceNameToImplName& aImplementation : aImplementations)
135 {
136 if ( sComponentURL == aImplementation.sServiceName )
137 {
138 xController.set( m_xContext->getServiceManager()->
139 createInstanceWithContext( OUString::createFromAscii( aImplementation.pAsciiImplementationName ), m_xContext), UNO_QUERY_THROW );
140 break;
141 }
142 }
143
144 // if a data source browser is loaded without its tree pane, then we assume it to be a
145 // table data view, effectively. In this case, we need to adjust the module identifier.
146 // #i85879#
147 ::comphelper::NamedValueCollection aLoadArgs( rArgs );
148
149 if ( sComponentURL == URL_COMPONENT_DATASOURCEBROWSER )
150 {
151 bool bDisableBrowser = !aLoadArgs.getOrDefault( "ShowTreeViewButton", true ) // compatibility name
152 || !aLoadArgs.getOrDefault( PROPERTY_ENABLE_BROWSER, true );
153
154 if ( bDisableBrowser )
155 {
156 try
157 {
158 Reference< XModule > xModule( xController, UNO_QUERY_THROW );
159 xModule->setIdentifier( "com.sun.star.sdb.TableDataView" );
160 }
161 catch( const Exception& )
162 {
163 DBG_UNHANDLED_EXCEPTION("dbaccess");
164 }
165 }
166 }
167
168 if ( sComponentURL == URL_COMPONENT_REPORTDESIGN )
169 {
170 bool bPreview = aLoadArgs.getOrDefault( "Preview", false );
171 if ( bPreview )
172 { // report designs cannot be previewed
173 if ( rListener.is() )
174 rListener->loadCancelled( this );
175 return;
176 }
177 Reference< XModel > xReportModel( aLoadArgs.getOrDefault( "Model", Reference< XModel >() ) );
178 if ( xReportModel.is() )
179 {
180 xController.set( ReportDesign::create( m_xContext ) );
182 }
183 }
184
185 bool bSuccess = xController.is();
186 Reference< XModel > xDatabaseDocument;
187 if ( bSuccess )
188 {
189 Reference< XDataSource > xDataSource ( aLoadArgs.getOrDefault( "DataSource", Reference< XDataSource >() ) );
190 OUString sDataSourceName( aLoadArgs.getOrDefault( "DataSourceName", OUString() ) );
191 Reference< XConnection > xConnection ( aLoadArgs.getOrDefault( "ActiveConnection", Reference< XConnection >() ) );
192 if ( xDataSource.is() )
193 {
194 xDatabaseDocument.set( getDataSourceOrModel( xDataSource ), UNO_QUERY );
195 }
196 else if ( !sDataSourceName.isEmpty() )
197 {
199 xDataSource.set( getDataSourceByName( sDataSourceName, nullptr, m_xContext, &aError ) );
200 xDatabaseDocument.set( getDataSourceOrModel( xDataSource ), UNO_QUERY );
201 }
202 else if ( xConnection.is() )
203 {
204 Reference< XChild > xAsChild( xConnection, UNO_QUERY );
205 if ( xAsChild.is() )
206 {
207 OSL_ENSURE( Reference< XDataSource >( xAsChild->getParent(), UNO_QUERY ).is(),
208 "DBContentLoader::load: a connection whose parent is no data source?" );
209 xDatabaseDocument.set( getDataSourceOrModel( xAsChild->getParent() ), UNO_QUERY );
210 }
211 }
212
213 // init controller
214 SolarMutexGuard aGuard;
215 try
216 {
218 PropertyValue aFrame("Frame",0,Any(rFrame),PropertyState_DIRECT_VALUE);
219 Sequence< Any > aInitArgs(m_aArgs.getLength()+1);
220
221 Any* pBegin = aInitArgs.getArray();
222 Any* pEnd = pBegin + aInitArgs.getLength();
223 *pBegin <<= aFrame;
224 const PropertyValue* pIter = m_aArgs.getConstArray();
225 for(++pBegin;pBegin != pEnd;++pBegin,++pIter)
226 {
227 *pBegin <<= *pIter;
228 }
229
230 xIni->initialize(aInitArgs);
231 }
232 catch(const Exception&)
233 {
234 // Does this need to be shown to the user?
235 bSuccess = false;
236 try
237 {
238 ::comphelper::disposeComponent( xController );
239 }
240 catch( const Exception& )
241 {
242 DBG_UNHANDLED_EXCEPTION("dbaccess");
243 }
244 }
245 }
246
247 // assign controller and frame
248 if ( bSuccess )
249 {
250 if ( xController.is() && rFrame.is() )
251 {
252 rFrame->setComponent( xController->getComponentWindow(), xController );
253 xController->attachFrame(rFrame);
254 }
255
256 if ( rListener.is() )
257 rListener->loadFinished( this );
258 }
259 else
260 if ( rListener.is() )
261 rListener->loadCancelled( this );
262}
263
264void DBContentLoader::cancel()
265{
266}
267
268/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
constexpr OUStringLiteral sServiceName
Reference< XComponentContext > m_xContext
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * org_openoffice_comp_dbu_DBContentLoader_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
Definition: dbloader.cxx:86
#define DBG_UNHANDLED_EXCEPTION(...)
Reference< XTextListener > m_xListener
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
css::uno::Reference< css::sdbc::XDataSource > getDataSourceByName(const OUString &_rDataSourceName, weld::Window *_pErrorMessageParent, const css::uno::Reference< css::uno::XComponentContext > &_rxContext, ::dbtools::SQLExceptionInfo *_pErrorInfo)
retrieves a data source given by name or URL, and displays an error if this fails
css::uno::Reference< css::uno::XInterface > getDataSourceOrModel(const css::uno::Reference< css::uno::XInterface > &_xObject)
returns either the model when data source is given as parameter, or returns a data source when a mode...
void ConnectModelController(const css::uno::Reference< css::frame::XModel > &xModel, const css::uno::Reference< css::frame::XController > &xController)
constexpr OUStringLiteral URL_COMPONENT_RELATIONDESIGN
Definition: strings.hxx:243
constexpr OUStringLiteral URL_COMPONENT_DATASOURCEBROWSER
Definition: strings.hxx:242
constexpr OUStringLiteral URL_COMPONENT_QUERYDESIGN
Definition: strings.hxx:237
constexpr OUStringLiteral URL_COMPONENT_VIEWDESIGN
Definition: strings.hxx:238
constexpr OUStringLiteral PROPERTY_ENABLE_BROWSER(u"EnableBrowser")
constexpr OUStringLiteral URL_COMPONENT_REPORTDESIGN(u".component:DB/ReportDesign")
constexpr OUStringLiteral URL_COMPONENT_TABLEDESIGN
Definition: strings.hxx:239
constexpr OUStringLiteral URL_COMPONENT_FORMGRIDVIEW
Definition: strings.hxx:240
Reference< XController > xController
the controller of the sub component. Must not be <NULL>
unsigned char sal_Bool