LibreOffice Module dbaccess (master) 1
databaseregistrations.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 <sal/config.h>
21
22#include <com/sun/star/lang/IllegalAccessException.hpp>
23#include <com/sun/star/lang/IllegalArgumentException.hpp>
24#include <com/sun/star/container/ElementExistException.hpp>
25#include <com/sun/star/container/NoSuchElementException.hpp>
26#include <com/sun/star/sdb/XDatabaseRegistrations.hpp>
27
31#include <osl/diagnose.h>
33#include <tools/urlobj.hxx>
35
37
38namespace dbaccess
39{
40 using ::com::sun::star::uno::Reference;
41 using ::com::sun::star::uno::RuntimeException;
42 using ::com::sun::star::uno::Any;
43 using ::com::sun::star::uno::Sequence;
44 using ::com::sun::star::uno::XComponentContext;
45 using ::com::sun::star::container::NoSuchElementException;
46 using ::com::sun::star::lang::IllegalArgumentException;
47 using ::com::sun::star::lang::IllegalAccessException;
48 using ::com::sun::star::container::ElementExistException;
49 using ::com::sun::star::sdb::XDatabaseRegistrations;
50 using ::com::sun::star::sdb::XDatabaseRegistrationsListener;
51 using ::com::sun::star::sdb::DatabaseRegistrationEvent;
52 using ::com::sun::star::uno::XAggregation;
53
54 static OUString getConfigurationRootPath()
55 {
56 return "org.openoffice.Office.DataAccess/RegisteredNames";
57 }
58
59 static OUString getLocationNodeName()
60 {
61 return "Location";
62 }
63
64 static OUString getNameNodeName()
65 {
66 return "Name";
67 }
68
69 // DatabaseRegistrations - declaration
70 typedef ::cppu::WeakAggImplHelper1 < XDatabaseRegistrations
72
73 namespace {
74
77 {
78 public:
79 explicit DatabaseRegistrations( const Reference<XComponentContext>& _rxContext );
80
81 protected:
82 virtual ~DatabaseRegistrations() override;
83
84 public:
85 virtual sal_Bool SAL_CALL hasRegisteredDatabase( const OUString& Name ) override;
86 virtual Sequence< OUString > SAL_CALL getRegistrationNames() override;
87 virtual OUString SAL_CALL getDatabaseLocation( const OUString& Name ) override;
88 virtual void SAL_CALL registerDatabaseLocation( const OUString& Name, const OUString& Location ) override;
89 virtual void SAL_CALL revokeDatabaseLocation( const OUString& Name ) override;
90 virtual void SAL_CALL changeDatabaseLocation( const OUString& Name, const OUString& NewLocation ) override;
91 virtual sal_Bool SAL_CALL isDatabaseRegistrationReadOnly( const OUString& Name ) override;
92 virtual void SAL_CALL addDatabaseRegistrationsListener( const Reference< XDatabaseRegistrationsListener >& Listener ) override;
93 virtual void SAL_CALL removeDatabaseRegistrationsListener( const Reference< XDatabaseRegistrationsListener >& Listener ) override;
94
95 private:
96 void
97 impl_checkValidName_common(std::u16string_view _rName);
99 impl_checkValidName_throw_must_exist(const OUString& _rName);
101 impl_checkValidName_throw_must_not_exist(const OUString& _rName);
102
103 void impl_checkValidLocation_throw( std::u16string_view _rLocation );
104
116 impl_getNodeForName_throw_must_exist(const OUString& _rName);
117
130 impl_getNodeForName_throw_must_not_exist(const OUString& _rName);
131
132
134 impl_getNodeForName_nothrow(std::u16string_view _rName);
135
136 private:
137 Reference<XComponentContext> m_aContext;
140 };
141
142 }
143
144 // DatabaseRegistrations - implementation
145 DatabaseRegistrations::DatabaseRegistrations( const Reference<XComponentContext> & _rxContext )
146 :m_aContext( _rxContext )
148 {
151 }
152
153 DatabaseRegistrations::~DatabaseRegistrations()
154 {
155 }
156
157 ::utl::OConfigurationNode DatabaseRegistrations::impl_getNodeForName_nothrow( std::u16string_view _rName )
158 {
159 const Sequence< OUString > aNames( m_aConfigurationRoot.getNodeNames() );
160 for ( auto const & nodeName : aNames )
161 {
163
164 OUString sTestName;
165 OSL_VERIFY( aNodeForName.getNodeValue( getNameNodeName() ) >>= sTestName );
166 if ( sTestName == _rName )
167 return aNodeForName;
168 }
169 return ::utl::OConfigurationNode();
170 }
171
172 ::utl::OConfigurationNode DatabaseRegistrations::impl_getNodeForName_throw_must_exist(const OUString& _rName)
173 {
174 ::utl::OConfigurationNode aNodeForName( impl_getNodeForName_nothrow( _rName ) );
175
176 if (!aNodeForName.isValid())
177 {
178 throw NoSuchElementException( _rName, *this );
179 }
180
181 return aNodeForName;
182 }
183
184 ::utl::OConfigurationNode DatabaseRegistrations::impl_getNodeForName_throw_must_not_exist(const OUString& _rName)
185 {
186 ::utl::OConfigurationNode aNodeForName( impl_getNodeForName_nothrow( _rName ) );
187
188 if (aNodeForName.isValid())
189 throw ElementExistException( _rName, *this );
190
191 // make unique
192 OUString sNewNodeName = "org.openoffice." + _rName;
193 while ( m_aConfigurationRoot.hasByName( sNewNodeName ) )
194 {
195 sNewNodeName = "org.openoffice." + _rName + " 2";
196 }
197
199 aNewNode.setNodeValue( getNameNodeName(), Any( _rName ) );
200 return aNewNode;
201 }
202
203 void DatabaseRegistrations::impl_checkValidName_common(std::u16string_view _rName)
204 {
206 throw RuntimeException( OUString(), *this );
207
208 if ( _rName.empty() )
209 throw IllegalArgumentException( OUString(), *this, 1 );
210 }
211
212 ::utl::OConfigurationNode DatabaseRegistrations::impl_checkValidName_throw_must_exist(const OUString& _rName)
213 {
214 impl_checkValidName_common(_rName);
215 return impl_getNodeForName_throw_must_exist(_rName);
216 }
217
218 ::utl::OConfigurationNode DatabaseRegistrations::impl_checkValidName_throw_must_not_exist(const OUString& _rName)
219 {
220 impl_checkValidName_common(_rName);
221 return impl_getNodeForName_throw_must_not_exist(_rName);
222 }
223
224 void DatabaseRegistrations::impl_checkValidLocation_throw( std::u16string_view _rLocation )
225 {
226 if ( _rLocation.empty() )
227 throw IllegalArgumentException( OUString(), *this, 2 );
228
229 INetURLObject aURL( _rLocation );
230 if ( aURL.GetProtocol() == INetProtocol::NotValid )
231 throw IllegalArgumentException( OUString(), *this, 2 );
232 }
233
234 sal_Bool SAL_CALL DatabaseRegistrations::hasRegisteredDatabase( const OUString& Name )
235 {
236 ::osl::MutexGuard aGuard( m_aMutex );
237 ::utl::OConfigurationNode aNodeForName = impl_getNodeForName_nothrow( Name );
238 return aNodeForName.isValid();
239 }
240
241 Sequence< OUString > SAL_CALL DatabaseRegistrations::getRegistrationNames()
242 {
243 ::osl::MutexGuard aGuard( m_aMutex );
245 throw RuntimeException( OUString(), *this );
246
247 const Sequence< OUString > aProgrammaticNames( m_aConfigurationRoot.getNodeNames() );
248 Sequence< OUString > aDisplayNames( aProgrammaticNames.getLength() );
249 OUString* pDisplayName = aDisplayNames.getArray();
250
251 for ( auto const & name : aProgrammaticNames )
252 {
253 ::utl::OConfigurationNode aRegistrationNode = m_aConfigurationRoot.openNode( name );
254 OSL_VERIFY( aRegistrationNode.getNodeValue( getNameNodeName() ) >>= *pDisplayName );
255 ++pDisplayName;
256 }
257
258 return aDisplayNames;
259 }
260
261 OUString SAL_CALL DatabaseRegistrations::getDatabaseLocation( const OUString& Name )
262 {
263 ::osl::MutexGuard aGuard( m_aMutex );
264
265 ::utl::OConfigurationNode aNodeForName = impl_checkValidName_throw_must_exist(Name);
266
267 OUString sLocation;
268 OSL_VERIFY( aNodeForName.getNodeValue( getLocationNodeName() ) >>= sLocation );
269 sLocation = SvtPathOptions().SubstituteVariable( sLocation );
270
271 return sLocation;
272 }
273
274 void SAL_CALL DatabaseRegistrations::registerDatabaseLocation( const OUString& Name, const OUString& Location )
275 {
276 ::osl::ClearableMutexGuard aGuard( m_aMutex );
277
278 // check
279 impl_checkValidLocation_throw( Location );
280 ::utl::OConfigurationNode aDataSourceRegistration = impl_checkValidName_throw_must_not_exist(Name);
281
282 // register
283 aDataSourceRegistration.setNodeValue( getLocationNodeName(), Any( Location ) );
285
286 // notify
287 DatabaseRegistrationEvent aEvent( *this, Name, OUString(), Location );
288 aGuard.clear();
289 m_aRegistrationListeners.notifyEach( &XDatabaseRegistrationsListener::registeredDatabaseLocation, aEvent );
290 }
291
292 void SAL_CALL DatabaseRegistrations::revokeDatabaseLocation( const OUString& Name )
293 {
294 ::osl::ClearableMutexGuard aGuard( m_aMutex );
295
296 // check
297 ::utl::OConfigurationNode aNodeForName = impl_checkValidName_throw_must_exist(Name);
298
299 // obtain properties for notification
300 OUString sLocation;
301 OSL_VERIFY( aNodeForName.getNodeValue( getLocationNodeName() ) >>= sLocation );
302
303 // revoke
304 if ( aNodeForName.isReadonly()
305 || !m_aConfigurationRoot.removeNode( aNodeForName.getLocalName() )
306 )
307 throw IllegalAccessException( OUString(), *this );
308
310
311 // notify
312 DatabaseRegistrationEvent aEvent( *this, Name, sLocation, OUString() );
313 aGuard.clear();
314 m_aRegistrationListeners.notifyEach( &XDatabaseRegistrationsListener::revokedDatabaseLocation, aEvent );
315 }
316
317 void SAL_CALL DatabaseRegistrations::changeDatabaseLocation( const OUString& Name, const OUString& NewLocation )
318 {
319 ::osl::ClearableMutexGuard aGuard( m_aMutex );
320
321 // check
322 impl_checkValidLocation_throw( NewLocation );
323 ::utl::OConfigurationNode aDataSourceRegistration = impl_checkValidName_throw_must_exist(Name);
324
325 if ( aDataSourceRegistration.isReadonly() )
326 throw IllegalAccessException( OUString(), *this );
327
328 // obtain properties for notification
329 OUString sOldLocation;
330 OSL_VERIFY( aDataSourceRegistration.getNodeValue( getLocationNodeName() ) >>= sOldLocation );
331
332 // change
333 aDataSourceRegistration.setNodeValue( getLocationNodeName(), Any( NewLocation ) );
335
336 // notify
337 DatabaseRegistrationEvent aEvent( *this, Name, sOldLocation, NewLocation );
338 aGuard.clear();
339 m_aRegistrationListeners.notifyEach( &XDatabaseRegistrationsListener::changedDatabaseLocation, aEvent );
340 }
341
342 sal_Bool SAL_CALL DatabaseRegistrations::isDatabaseRegistrationReadOnly( const OUString& Name )
343 {
344 ::osl::MutexGuard aGuard( m_aMutex );
345 ::utl::OConfigurationNode aDataSourceRegistration = impl_checkValidName_throw_must_exist(Name);
346 return aDataSourceRegistration.isReadonly();
347 }
348
349 void SAL_CALL DatabaseRegistrations::addDatabaseRegistrationsListener( const Reference< XDatabaseRegistrationsListener >& Listener )
350 {
351 if ( Listener.is() )
352 m_aRegistrationListeners.addInterface( Listener );
353 }
354
355 void SAL_CALL DatabaseRegistrations::removeDatabaseRegistrationsListener( const Reference< XDatabaseRegistrationsListener >& Listener )
356 {
357 if ( Listener.is() )
358 m_aRegistrationListeners.removeInterface( Listener );
359 }
360
361 // DatabaseRegistrations - factory
362 Reference< XAggregation > createDataSourceRegistrations( const Reference<XComponentContext> & _rxContext )
363 {
364 return new DatabaseRegistrations( _rxContext );
365 }
366
367} // namespace dbaccess
368
369/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
AnyEventRef aEvent
OUString SubstituteVariable(const OUString &rVar) const
css::uno::Sequence< OUString > getNodeNames() const noexcept
css::uno::Any getNodeValue(const OUString &_rPath) const noexcept
bool hasByName(const OUString &_rName) const noexcept
bool removeNode(const OUString &_rName) const noexcept
OUString getLocalName() const
bool setNodeValue(const OUString &_rPath, const css::uno::Any &_rValue) const noexcept
OConfigurationNode createNode(const OUString &_rName) const noexcept
OConfigurationNode openNode(const OUString &_rPath) const noexcept
static OConfigurationTreeRoot createWithComponentContext(const css::uno::Reference< css::uno::XComponentContext > &_rxContext, const OUString &_rPath, sal_Int32 _nDepth=-1, CREATION_MODE _eMode=CM_UPDATABLE)
bool commit() const noexcept
::comphelper::OInterfaceContainerHelper3< XDatabaseRegistrationsListener > m_aRegistrationListeners
::utl::OConfigurationTreeRoot m_aConfigurationRoot
Reference< XComponentContext > m_aContext
std::mutex m_aMutex
URL aURL
Definition: intercept.cxx:87
::cppu::WeakAggImplHelper1< XDatabaseRegistrations > DatabaseRegistrations_Base
Reference< XAggregation > createDataSourceRegistrations(const Reference< XComponentContext > &_rxContext)
static OUString getConfigurationRootPath()
static OUString getNameNodeName()
static OUString getLocationNodeName()
std::map< OUString, DatabaseRegistration > DatabaseRegistrations
OUString Name
unsigned char sal_Bool