tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / dbaccess / source / core / dataaccess / databaseregistrations.cxx
bloba328eb39ecf818b812ac85df6a6106a8a5a6e26e
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 <sal/config.h>
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>
28 #include <cppuhelper/basemutex.hxx>
29 #include <comphelper/interfacecontainer3.hxx>
30 #include <cppuhelper/implbase.hxx>
31 #include <osl/diagnose.h>
32 #include <unotools/pathoptions.hxx>
33 #include <tools/urlobj.hxx>
34 #include <unotools/confignode.hxx>
36 #include "databaseregistrations.hxx"
38 namespace dbaccess
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;
53 constexpr OUString CONF_ROOT_PATH = u"org.openoffice.Office.DataAccess/RegisteredNames"_ustr;
54 constexpr OUString LOCATION = u"Location"_ustr;
55 constexpr OUString NAME = u"Name"_ustr;
57 // DatabaseRegistrations - declaration
58 typedef ::cppu::WeakImplHelper< XDatabaseRegistrations
59 > DatabaseRegistrations_Base;
61 namespace {
63 class DatabaseRegistrations :public ::cppu::BaseMutex
64 ,public DatabaseRegistrations_Base
66 public:
67 explicit DatabaseRegistrations( const Reference<XComponentContext>& _rxContext );
69 protected:
70 virtual ~DatabaseRegistrations() override;
72 public:
73 virtual sal_Bool SAL_CALL hasRegisteredDatabase( const OUString& Name ) override;
74 virtual Sequence< OUString > SAL_CALL getRegistrationNames() override;
75 virtual OUString SAL_CALL getDatabaseLocation( const OUString& Name ) override;
76 virtual void SAL_CALL registerDatabaseLocation( const OUString& Name, const OUString& Location ) override;
77 virtual void SAL_CALL revokeDatabaseLocation( const OUString& Name ) override;
78 virtual void SAL_CALL changeDatabaseLocation( const OUString& Name, const OUString& NewLocation ) override;
79 virtual sal_Bool SAL_CALL isDatabaseRegistrationReadOnly( const OUString& Name ) override;
80 virtual void SAL_CALL addDatabaseRegistrationsListener( const Reference< XDatabaseRegistrationsListener >& Listener ) override;
81 virtual void SAL_CALL removeDatabaseRegistrationsListener( const Reference< XDatabaseRegistrationsListener >& Listener ) override;
83 private:
84 void
85 impl_checkValidName_common(std::u16string_view _rName);
86 ::utl::OConfigurationNode
87 impl_checkValidName_throw_must_exist(const OUString& _rName);
88 ::utl::OConfigurationNode
89 impl_checkValidName_throw_must_not_exist(const OUString& _rName);
91 void impl_checkValidLocation_throw( std::u16string_view _rLocation );
93 /** retrieves the configuration node whose "Name" sub node has the given value
95 Since we separated the name of the registration node from the "Name" value of the registration, we cannot
96 simply do a "getByName" (equivalent) when we want to retrieve the node for a given registration name.
97 Instead, we must search all nodes.
99 If a node with the given display name does not exist, then a NoSuchElementException is thrown.
101 If no exception is thrown, then a valid node is returned: If the node existed it is returned.
103 ::utl::OConfigurationNode
104 impl_getNodeForName_throw_must_exist(const OUString& _rName);
106 /** retrieves the configuration node whose "Name" sub node has the given value
108 Since we separated the name of the registration node from the "Name" value of the registration, we cannot
109 simply do a "getByName" (equivalent) when we want to retrieve the node for a given registration name.
110 Instead, we must search all nodes.
112 If a node with the given name already exists, then an ElementExistException is thrown.
114 If no exception is thrown, then a valid node is returned: If the node did not yet exist a new node is created,
115 in this case the root node is not yet committed.
117 ::utl::OConfigurationNode
118 impl_getNodeForName_throw_must_not_exist(const OUString& _rName);
121 ::utl::OConfigurationNode
122 impl_getNodeForName_nothrow(std::u16string_view _rName);
124 private:
125 Reference<XComponentContext> m_aContext;
126 ::utl::OConfigurationTreeRoot m_aConfigurationRoot;
127 ::comphelper::OInterfaceContainerHelper3<XDatabaseRegistrationsListener> m_aRegistrationListeners;
132 // DatabaseRegistrations - implementation
133 DatabaseRegistrations::DatabaseRegistrations( const Reference<XComponentContext> & _rxContext )
134 :m_aContext( _rxContext )
135 ,m_aRegistrationListeners( m_aMutex )
137 m_aConfigurationRoot = ::utl::OConfigurationTreeRoot::createWithComponentContext(
138 m_aContext, CONF_ROOT_PATH );
141 DatabaseRegistrations::~DatabaseRegistrations()
145 ::utl::OConfigurationNode DatabaseRegistrations::impl_getNodeForName_nothrow( std::u16string_view _rName )
147 const Sequence< OUString > aNames( m_aConfigurationRoot.getNodeNames() );
148 for ( auto const & nodeName : aNames )
150 ::utl::OConfigurationNode aNodeForName = m_aConfigurationRoot.openNode( nodeName );
152 OUString sTestName;
153 OSL_VERIFY( aNodeForName.getNodeValue( NAME ) >>= sTestName );
154 if ( sTestName == _rName )
155 return aNodeForName;
157 return ::utl::OConfigurationNode();
160 ::utl::OConfigurationNode DatabaseRegistrations::impl_getNodeForName_throw_must_exist(const OUString& _rName)
162 ::utl::OConfigurationNode aNodeForName( impl_getNodeForName_nothrow( _rName ) );
164 if (!aNodeForName.isValid())
166 throw NoSuchElementException( _rName, *this );
169 return aNodeForName;
172 ::utl::OConfigurationNode DatabaseRegistrations::impl_getNodeForName_throw_must_not_exist(const OUString& _rName)
174 ::utl::OConfigurationNode aNodeForName( impl_getNodeForName_nothrow( _rName ) );
176 if (aNodeForName.isValid())
177 throw ElementExistException( _rName, *this );
179 // make unique
180 OUString sNewNodeName = "org.openoffice." + _rName;
181 while ( m_aConfigurationRoot.hasByName( sNewNodeName ) )
183 sNewNodeName = "org.openoffice." + _rName + " 2";
186 ::utl::OConfigurationNode aNewNode( m_aConfigurationRoot.createNode( sNewNodeName ) );
187 aNewNode.setNodeValue( NAME, Any( _rName ) );
188 return aNewNode;
191 void DatabaseRegistrations::impl_checkValidName_common(std::u16string_view _rName)
193 if ( !m_aConfigurationRoot.isValid() )
194 throw RuntimeException( OUString(), *this );
196 if ( _rName.empty() )
197 throw IllegalArgumentException( OUString(), *this, 1 );
200 ::utl::OConfigurationNode DatabaseRegistrations::impl_checkValidName_throw_must_exist(const OUString& _rName)
202 impl_checkValidName_common(_rName);
203 return impl_getNodeForName_throw_must_exist(_rName);
206 ::utl::OConfigurationNode DatabaseRegistrations::impl_checkValidName_throw_must_not_exist(const OUString& _rName)
208 impl_checkValidName_common(_rName);
209 return impl_getNodeForName_throw_must_not_exist(_rName);
212 void DatabaseRegistrations::impl_checkValidLocation_throw( std::u16string_view _rLocation )
214 if ( _rLocation.empty() )
215 throw IllegalArgumentException( OUString(), *this, 2 );
217 INetURLObject aURL( _rLocation );
218 if ( aURL.GetProtocol() == INetProtocol::NotValid )
219 throw IllegalArgumentException( OUString(), *this, 2 );
222 sal_Bool SAL_CALL DatabaseRegistrations::hasRegisteredDatabase( const OUString& Name )
224 ::osl::MutexGuard aGuard( m_aMutex );
225 ::utl::OConfigurationNode aNodeForName = impl_getNodeForName_nothrow( Name );
226 return aNodeForName.isValid();
229 Sequence< OUString > SAL_CALL DatabaseRegistrations::getRegistrationNames()
231 ::osl::MutexGuard aGuard( m_aMutex );
232 if ( !m_aConfigurationRoot.isValid() )
233 throw RuntimeException( OUString(), *this );
235 const Sequence< OUString > aProgrammaticNames( m_aConfigurationRoot.getNodeNames() );
236 Sequence< OUString > aDisplayNames( aProgrammaticNames.getLength() );
237 OUString* pDisplayName = aDisplayNames.getArray();
239 for ( auto const & name : aProgrammaticNames )
241 ::utl::OConfigurationNode aRegistrationNode = m_aConfigurationRoot.openNode( name );
242 OSL_VERIFY( aRegistrationNode.getNodeValue( NAME ) >>= *pDisplayName );
243 ++pDisplayName;
246 return aDisplayNames;
249 OUString SAL_CALL DatabaseRegistrations::getDatabaseLocation( const OUString& Name )
251 ::osl::MutexGuard aGuard( m_aMutex );
253 ::utl::OConfigurationNode aNodeForName = impl_checkValidName_throw_must_exist(Name);
255 OUString sLocation;
256 OSL_VERIFY( aNodeForName.getNodeValue( LOCATION ) >>= sLocation );
257 sLocation = SvtPathOptions().SubstituteVariable( sLocation );
259 return sLocation;
262 void SAL_CALL DatabaseRegistrations::registerDatabaseLocation( const OUString& Name, const OUString& Location )
264 ::osl::ClearableMutexGuard aGuard( m_aMutex );
266 // check
267 impl_checkValidLocation_throw( Location );
268 ::utl::OConfigurationNode aDataSourceRegistration = impl_checkValidName_throw_must_not_exist(Name);
270 // register
271 aDataSourceRegistration.setNodeValue( LOCATION, Any( Location ) );
272 m_aConfigurationRoot.commit();
274 // notify
275 DatabaseRegistrationEvent aEvent( *this, Name, OUString(), Location );
276 aGuard.clear();
277 m_aRegistrationListeners.notifyEach( &XDatabaseRegistrationsListener::registeredDatabaseLocation, aEvent );
280 void SAL_CALL DatabaseRegistrations::revokeDatabaseLocation( const OUString& Name )
282 ::osl::ClearableMutexGuard aGuard( m_aMutex );
284 // check
285 ::utl::OConfigurationNode aNodeForName = impl_checkValidName_throw_must_exist(Name);
287 // obtain properties for notification
288 OUString sLocation;
289 OSL_VERIFY( aNodeForName.getNodeValue( LOCATION ) >>= sLocation );
291 // revoke
292 if ( aNodeForName.isReadonly()
293 || !m_aConfigurationRoot.removeNode( aNodeForName.getLocalName() )
295 throw IllegalAccessException( OUString(), *this );
297 m_aConfigurationRoot.commit();
299 // notify
300 DatabaseRegistrationEvent aEvent( *this, Name, sLocation, OUString() );
301 aGuard.clear();
302 m_aRegistrationListeners.notifyEach( &XDatabaseRegistrationsListener::revokedDatabaseLocation, aEvent );
305 void SAL_CALL DatabaseRegistrations::changeDatabaseLocation( const OUString& Name, const OUString& NewLocation )
307 ::osl::ClearableMutexGuard aGuard( m_aMutex );
309 // check
310 impl_checkValidLocation_throw( NewLocation );
311 ::utl::OConfigurationNode aDataSourceRegistration = impl_checkValidName_throw_must_exist(Name);
313 if ( aDataSourceRegistration.isReadonly() )
314 throw IllegalAccessException( OUString(), *this );
316 // obtain properties for notification
317 OUString sOldLocation;
318 OSL_VERIFY( aDataSourceRegistration.getNodeValue( LOCATION ) >>= sOldLocation );
320 // change
321 aDataSourceRegistration.setNodeValue( LOCATION, Any( NewLocation ) );
322 m_aConfigurationRoot.commit();
324 // notify
325 DatabaseRegistrationEvent aEvent( *this, Name, sOldLocation, NewLocation );
326 aGuard.clear();
327 m_aRegistrationListeners.notifyEach( &XDatabaseRegistrationsListener::changedDatabaseLocation, aEvent );
330 sal_Bool SAL_CALL DatabaseRegistrations::isDatabaseRegistrationReadOnly( const OUString& Name )
332 ::osl::MutexGuard aGuard( m_aMutex );
333 ::utl::OConfigurationNode aDataSourceRegistration = impl_checkValidName_throw_must_exist(Name);
334 return aDataSourceRegistration.isReadonly();
337 void SAL_CALL DatabaseRegistrations::addDatabaseRegistrationsListener( const Reference< XDatabaseRegistrationsListener >& Listener )
339 if ( Listener.is() )
340 m_aRegistrationListeners.addInterface( Listener );
343 void SAL_CALL DatabaseRegistrations::removeDatabaseRegistrationsListener( const Reference< XDatabaseRegistrationsListener >& Listener )
345 if ( Listener.is() )
346 m_aRegistrationListeners.removeInterface( Listener );
349 // DatabaseRegistrations - factory
350 Reference< XDatabaseRegistrations > createDataSourceRegistrations( const Reference<XComponentContext> & _rxContext )
352 return new DatabaseRegistrations( _rxContext );
355 } // namespace dbaccess
357 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */