tdf#154285 Check upper bound of arguments in SbRtl_Minute function
[LibreOffice.git] / dbaccess / source / ui / browser / dbloader.cxx
blobba4e206d446c59dc54a2e06cc86caf2fa317b9a3
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <strings.hxx>
21 #include <UITools.hxx>
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>
34 #include <com/sun/star/sdbc/XDataSource.hpp>
35 #include <comphelper/namedvaluecollection.hxx>
36 #include <comphelper/types.hxx>
37 #include <cppuhelper/implbase.hxx>
38 #include <cppuhelper/supportsservice.hxx>
39 #include <comphelper/diagnose_ex.hxx>
40 #include <tools/urlobj.hxx>
41 #include <unotools/fcm.hxx>
42 #include <vcl/svapp.hxx>
44 using namespace ::com::sun::star;
45 using namespace ::com::sun::star::uno;
46 using namespace ::com::sun::star::frame;
47 using namespace ::com::sun::star::beans;
48 using namespace ::com::sun::star::sdb;
49 using namespace ::com::sun::star::sdbc;
50 using namespace ::com::sun::star::container;
51 using namespace ::com::sun::star::lang;
52 using namespace dbaui;
54 namespace {
56 class DBContentLoader : public ::cppu::WeakImplHelper< XFrameLoader, XServiceInfo>
58 private:
59 Sequence< PropertyValue> m_aArgs;
60 Reference< XLoadEventListener > m_xListener;
61 Reference< XComponentContext > m_xContext;
62 public:
63 explicit DBContentLoader(const Reference< XComponentContext >&);
65 // XServiceInfo
66 OUString SAL_CALL getImplementationName() override;
67 sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override;
68 Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
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;
79 DBContentLoader::DBContentLoader(const Reference< XComponentContext >& _rxContext)
80 :m_xContext(_rxContext)
85 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
86 org_openoffice_comp_dbu_DBContentLoader_get_implementation(
87 css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& )
89 return cppu::acquire(new DBContentLoader(context));
92 // XServiceInfo
93 OUString SAL_CALL DBContentLoader::getImplementationName()
95 return u"org.openoffice.comp.dbu.DBContentLoader"_ustr;
98 // XServiceInfo
99 sal_Bool SAL_CALL DBContentLoader::supportsService(const OUString& ServiceName)
101 return cppu::supportsService(this, ServiceName);
104 // XServiceInfo
105 Sequence< OUString > SAL_CALL DBContentLoader::getSupportedServiceNames()
107 return { u"com.sun.star.frame.FrameLoader"_ustr, u"com.sun.star.sdb.ContentLoader"_ustr };
110 void SAL_CALL DBContentLoader::load(const Reference< XFrame > & rFrame, const OUString& rURL,
111 const Sequence< PropertyValue >& rArgs,
112 const Reference< XLoadEventListener > & rListener)
114 m_xListener = rListener;
115 m_aArgs = rArgs;
117 static constexpr struct ServiceNameToImplName
119 OUString sServiceName;
120 OUString aAsciiImplementationName;
121 } aImplementations[] = {
122 { URL_COMPONENT_FORMGRIDVIEW, u"org.openoffice.comp.dbu.OFormGridView"_ustr },
123 { URL_COMPONENT_DATASOURCEBROWSER, u"org.openoffice.comp.dbu.ODatasourceBrowser"_ustr },
124 { URL_COMPONENT_QUERYDESIGN, u"org.openoffice.comp.dbu.OQueryDesign"_ustr },
125 { URL_COMPONENT_TABLEDESIGN, u"org.openoffice.comp.dbu.OTableDesign"_ustr },
126 { URL_COMPONENT_RELATIONDESIGN, u"org.openoffice.comp.dbu.ORelationDesign"_ustr },
127 { URL_COMPONENT_VIEWDESIGN, u"org.openoffice.comp.dbu.OViewDesign"_ustr }
130 INetURLObject aParser( rURL );
131 Reference< XController2 > xController;
133 const OUString sComponentURL( aParser.GetMainURL( INetURLObject::DecodeMechanism::ToIUri ) );
134 for (const ServiceNameToImplName& aImplementation : aImplementations)
136 if ( sComponentURL == aImplementation.sServiceName )
138 xController.set( m_xContext->getServiceManager()->
139 createInstanceWithContext( aImplementation.aAsciiImplementationName, m_xContext), UNO_QUERY_THROW );
140 break;
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 );
149 if ( sComponentURL == URL_COMPONENT_DATASOURCEBROWSER )
151 bool bDisableBrowser = !aLoadArgs.getOrDefault( u"ShowTreeViewButton"_ustr, true ) // compatibility name
152 || !aLoadArgs.getOrDefault( PROPERTY_ENABLE_BROWSER, true );
154 if ( bDisableBrowser )
158 Reference< XModule > xModule( xController, UNO_QUERY_THROW );
159 xModule->setIdentifier( u"com.sun.star.sdb.TableDataView"_ustr );
161 catch( const Exception& )
163 DBG_UNHANDLED_EXCEPTION("dbaccess");
168 if ( sComponentURL == URL_COMPONENT_REPORTDESIGN )
170 bool bPreview = aLoadArgs.getOrDefault( u"Preview"_ustr, false );
171 if ( bPreview )
172 { // report designs cannot be previewed
173 if ( rListener.is() )
174 rListener->loadCancelled( this );
175 return;
177 Reference< XModel > xReportModel( aLoadArgs.getOrDefault( u"Model"_ustr, Reference< XModel >() ) );
178 if ( xReportModel.is() )
180 xController.set( ReportDesign::create( m_xContext ) );
181 utl::ConnectModelController(xReportModel, xController);
185 bool bSuccess = xController.is();
186 Reference< XModel > xDatabaseDocument;
187 if ( bSuccess )
189 Reference< XDataSource > xDataSource ( aLoadArgs.getOrDefault( u"DataSource"_ustr, Reference< XDataSource >() ) );
190 OUString sDataSourceName( aLoadArgs.getOrDefault( u"DataSourceName"_ustr, OUString() ) );
191 Reference< XConnection > xConnection ( aLoadArgs.getOrDefault( u"ActiveConnection"_ustr, Reference< XConnection >() ) );
192 if ( xDataSource.is() )
194 xDatabaseDocument.set( getDataSourceOrModel( xDataSource ), UNO_QUERY );
196 else if ( !sDataSourceName.isEmpty() )
198 ::dbtools::SQLExceptionInfo aError;
199 xDataSource.set( getDataSourceByName( sDataSourceName, nullptr, m_xContext, &aError ) );
200 xDatabaseDocument.set( getDataSourceOrModel( xDataSource ), UNO_QUERY );
202 else if ( xConnection.is() )
204 Reference< XChild > xAsChild( xConnection, UNO_QUERY );
205 if ( xAsChild.is() )
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 );
213 // init controller
214 SolarMutexGuard aGuard;
217 Reference<XInitialization > xIni(xController,UNO_QUERY);
218 PropertyValue aFrame(u"Frame"_ustr,0,Any(rFrame),PropertyState_DIRECT_VALUE);
219 Sequence< Any > aInitArgs(m_aArgs.getLength()+1);
221 Any* pBegin = aInitArgs.getArray();
222 *pBegin <<= aFrame;
223 std::transform(m_aArgs.begin(), m_aArgs.end(), ++pBegin,
224 [](auto& val) { return Any(val); });
226 xIni->initialize(aInitArgs);
228 catch(const Exception&)
230 // Does this need to be shown to the user?
231 bSuccess = false;
234 ::comphelper::disposeComponent( xController );
236 catch( const Exception& )
238 DBG_UNHANDLED_EXCEPTION("dbaccess");
243 // assign controller and frame
244 if ( bSuccess )
246 if ( xController.is() && rFrame.is() )
248 rFrame->setComponent( xController->getComponentWindow(), xController );
249 xController->attachFrame(rFrame);
252 if ( rListener.is() )
253 rListener->loadFinished( this );
255 else
256 if ( rListener.is() )
257 rListener->loadCancelled( this );
260 void DBContentLoader::cancel()
264 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */