summaryrefslogtreecommitdiff
path: root/dbaccess/source/core/dataaccess/databaseregistrations.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'dbaccess/source/core/dataaccess/databaseregistrations.cxx')
-rw-r--r--dbaccess/source/core/dataaccess/databaseregistrations.cxx399
1 files changed, 399 insertions, 0 deletions
diff --git a/dbaccess/source/core/dataaccess/databaseregistrations.cxx b/dbaccess/source/core/dataaccess/databaseregistrations.cxx
new file mode 100644
index 000000000000..6a8e7db21236
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/databaseregistrations.cxx
@@ -0,0 +1,399 @@
+/*************************************************************************
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dbaccess.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/sdb/XDatabaseRegistrations.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/componentcontext.hxx>
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/interfacecontainer.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <unotools/pathoptions.hxx>
+#include <tools/urlobj.hxx>
+#include <unotools/confignode.hxx>
+
+//........................................................................
+namespace dbaccess
+{
+//........................................................................
+
+ /** === begin UNO using === **/
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::uno::XInterface;
+ using ::com::sun::star::uno::UNO_QUERY;
+ using ::com::sun::star::uno::UNO_QUERY_THROW;
+ using ::com::sun::star::uno::UNO_SET_THROW;
+ using ::com::sun::star::uno::Exception;
+ using ::com::sun::star::uno::RuntimeException;
+ using ::com::sun::star::uno::Any;
+ using ::com::sun::star::uno::makeAny;
+ using ::com::sun::star::uno::Sequence;
+ using ::com::sun::star::uno::Type;
+ using ::com::sun::star::container::NoSuchElementException;
+ using ::com::sun::star::lang::IllegalArgumentException;
+ using ::com::sun::star::lang::IllegalAccessException;
+ using ::com::sun::star::container::ElementExistException;
+ using ::com::sun::star::sdb::XDatabaseRegistrations;
+ using ::com::sun::star::sdb::XDatabaseRegistrationsListener;
+ using ::com::sun::star::sdb::DatabaseRegistrationEvent;
+ using ::com::sun::star::uno::XAggregation;
+ /** === end UNO using === **/
+
+ //--------------------------------------------------------------------
+ static const ::rtl::OUString& getConfigurationRootPath()
+ {
+ static ::rtl::OUString s_sNodeName = ::rtl::OUString::createFromAscii("org.openoffice.Office.DataAccess/RegisteredNames");
+ return s_sNodeName;
+ }
+
+ //--------------------------------------------------------------------
+ const ::rtl::OUString& getLocationNodeName()
+ {
+ static ::rtl::OUString s_sNodeName = ::rtl::OUString::createFromAscii( "Location" );
+ return s_sNodeName;
+ }
+
+ //--------------------------------------------------------------------
+ const ::rtl::OUString& getNameNodeName()
+ {
+ static ::rtl::OUString s_sNodeName = ::rtl::OUString::createFromAscii( "Name" );
+ return s_sNodeName;
+ }
+
+ //====================================================================
+ //= DatabaseRegistrations - declaration
+ //====================================================================
+ typedef ::cppu::WeakAggImplHelper1 < XDatabaseRegistrations
+ > DatabaseRegistrations_Base;
+ class DatabaseRegistrations :public ::cppu::BaseMutex
+ ,public DatabaseRegistrations_Base
+ {
+ public:
+ DatabaseRegistrations( const ::comphelper::ComponentContext& _rxContext );
+
+ protected:
+ ~DatabaseRegistrations();
+
+ public:
+ virtual ::sal_Bool SAL_CALL hasRegisteredDatabase( const ::rtl::OUString& _Name ) throw (IllegalArgumentException, RuntimeException);
+ virtual Sequence< ::rtl::OUString > SAL_CALL getRegistrationNames() throw (RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getDatabaseLocation( const ::rtl::OUString& _Name ) throw (IllegalArgumentException, NoSuchElementException, RuntimeException);
+ virtual void SAL_CALL registerDatabaseLocation( const ::rtl::OUString& _Name, const ::rtl::OUString& _Location ) throw (IllegalArgumentException, ElementExistException, RuntimeException);
+ virtual void SAL_CALL revokeDatabaseLocation( const ::rtl::OUString& _Name ) throw (IllegalArgumentException, NoSuchElementException, IllegalAccessException, RuntimeException);
+ virtual void SAL_CALL changeDatabaseLocation( const ::rtl::OUString& Name, const ::rtl::OUString& NewLocation ) throw (IllegalArgumentException, NoSuchElementException, IllegalAccessException, RuntimeException);
+ virtual ::sal_Bool SAL_CALL isDatabaseRegistrationReadOnly( const ::rtl::OUString& _Name ) throw (IllegalArgumentException, NoSuchElementException, RuntimeException);
+ virtual void SAL_CALL addDatabaseRegistrationsListener( const Reference< XDatabaseRegistrationsListener >& Listener ) throw (RuntimeException);
+ virtual void SAL_CALL removeDatabaseRegistrationsListener( const Reference< XDatabaseRegistrationsListener >& Listener ) throw (RuntimeException);
+
+ private:
+ ::utl::OConfigurationNode
+ impl_checkValidName_throw( const ::rtl::OUString& _rName, const bool _bMustExist );
+
+ void impl_checkValidLocation_throw( const ::rtl::OUString& _rLocation );
+
+ /** retrieves the configuration node whose "Name" sub node has the given value
+
+ Since we separated the name of the registration node from the "Name" value of the registration, we cannot
+ simply do a "getByName" (equivalent) when we want to retrieve the node for a given registration name.
+ Instead, we must search all nodes.
+
+ If _bMustExist is <TRUE/>, and a node with the given display name does not exist, then a NoSuchElementException
+ is thrown.
+
+ If _bMustExist is <FALSE/>, and a node with the given name already exists, then a ElementExistException is
+ thrown.
+
+ In either case, if no exception is thrown, then a valid node is returned: If the node existed and was allowed
+ to exist, it is returned, if the node did not yet exist, and was required to not exist, a new node is created.
+ However, in this case the root node is not yet committed.
+ */
+ ::utl::OConfigurationNode
+ impl_getNodeForName_throw( const ::rtl::OUString& _rName, const bool _bMustExist );
+
+ ::utl::OConfigurationNode
+ impl_getNodeForName_nothrow( const ::rtl::OUString& _rName );
+
+ private:
+ ::comphelper::ComponentContext m_aContext;
+ ::utl::OConfigurationTreeRoot m_aConfigurationRoot;
+ ::cppu::OInterfaceContainerHelper m_aRegistrationListeners;
+ };
+
+ //====================================================================
+ //= DatabaseRegistrations - implementation
+ //====================================================================
+ //--------------------------------------------------------------------
+ DatabaseRegistrations::DatabaseRegistrations( const ::comphelper::ComponentContext& _rxContext )
+ :m_aContext( _rxContext )
+ ,m_aConfigurationRoot()
+ ,m_aRegistrationListeners( m_aMutex )
+ {
+ m_aConfigurationRoot = ::utl::OConfigurationTreeRoot::createWithServiceFactory(
+ m_aContext.getLegacyServiceFactory(), getConfigurationRootPath(), -1, ::utl::OConfigurationTreeRoot::CM_UPDATABLE );
+ }
+
+ //--------------------------------------------------------------------
+ DatabaseRegistrations::~DatabaseRegistrations()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ ::utl::OConfigurationNode DatabaseRegistrations::impl_getNodeForName_nothrow( const ::rtl::OUString& _rName )
+ {
+ Sequence< ::rtl::OUString > aNames( m_aConfigurationRoot.getNodeNames() );
+ for ( const ::rtl::OUString* pName = aNames.getConstArray();
+ pName != aNames.getConstArray() + aNames.getLength();
+ ++pName
+ )
+ {
+ ::utl::OConfigurationNode aNodeForName = m_aConfigurationRoot.openNode( *pName );
+
+ ::rtl::OUString sTestName;
+ OSL_VERIFY( aNodeForName.getNodeValue( getNameNodeName() ) >>= sTestName );
+ if ( sTestName == _rName )
+ return aNodeForName;
+ }
+ return ::utl::OConfigurationNode();
+ }
+
+ //--------------------------------------------------------------------
+ ::utl::OConfigurationNode DatabaseRegistrations::impl_getNodeForName_throw( const ::rtl::OUString& _rName, const bool _bMustExist )
+ {
+ ::utl::OConfigurationNode aNodeForName( impl_getNodeForName_nothrow( _rName ) );
+
+ if ( aNodeForName.isValid() )
+ {
+ if ( !_bMustExist )
+ throw ElementExistException( _rName, *this );
+
+ return aNodeForName;
+ }
+
+ if ( _bMustExist )
+ throw NoSuchElementException( _rName, *this );
+
+ ::rtl::OUString sNewNodeName;
+ {
+ ::rtl::OUStringBuffer aNewNodeName;
+ aNewNodeName.appendAscii( "org.openoffice." );
+ aNewNodeName.append( _rName );
+
+ // make unique
+ ::rtl::OUStringBuffer aReset( aNewNodeName );
+ sNewNodeName = aNewNodeName.makeStringAndClear();
+ sal_Int32 i=2;
+ while ( m_aConfigurationRoot.hasByName( sNewNodeName ) )
+ {
+ aNewNodeName = aReset;
+ aNewNodeName.appendAscii( " " );
+ aNewNodeName.append( i );
+ sNewNodeName = aNewNodeName.makeStringAndClear();
+ }
+ }
+
+ ::utl::OConfigurationNode aNewNode( m_aConfigurationRoot.createNode( sNewNodeName ) );
+ aNewNode.setNodeValue( getNameNodeName(), makeAny( _rName ) );
+ return aNewNode;
+ }
+
+ //--------------------------------------------------------------------
+ ::utl::OConfigurationNode DatabaseRegistrations::impl_checkValidName_throw( const ::rtl::OUString& _rName, const bool _bMustExist )
+ {
+ if ( !m_aConfigurationRoot.isValid() )
+ throw RuntimeException( ::rtl::OUString(), *this );
+
+ if ( !_rName.getLength() )
+ throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
+
+ return impl_getNodeForName_throw( _rName, _bMustExist );
+ }
+
+ //--------------------------------------------------------------------
+ void DatabaseRegistrations::impl_checkValidLocation_throw( const ::rtl::OUString& _rLocation )
+ {
+ if ( !_rLocation.getLength() )
+ throw IllegalArgumentException( ::rtl::OUString(), *this, 2 );
+
+ INetURLObject aURL( _rLocation );
+ if ( aURL.GetProtocol() == INET_PROT_NOT_VALID )
+ throw IllegalArgumentException( ::rtl::OUString(), *this, 2 );
+ }
+
+ //--------------------------------------------------------------------
+ ::sal_Bool SAL_CALL DatabaseRegistrations::hasRegisteredDatabase( const ::rtl::OUString& _Name ) throw (IllegalArgumentException, RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ ::utl::OConfigurationNode aNodeForName = impl_getNodeForName_nothrow( _Name );
+ return aNodeForName.isValid();
+ }
+
+ //------------------------------------------------------------------------------
+ Sequence< ::rtl::OUString > SAL_CALL DatabaseRegistrations::getRegistrationNames() throw (RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( !m_aConfigurationRoot.isValid() )
+ throw RuntimeException( ::rtl::OUString(), *this );
+
+ Sequence< ::rtl::OUString > aProgrammaticNames( m_aConfigurationRoot.getNodeNames() );
+ Sequence< ::rtl::OUString > aDisplayNames( aProgrammaticNames.getLength() );
+ ::rtl::OUString* pDisplayName = aDisplayNames.getArray();
+
+ for ( const ::rtl::OUString* pName = aProgrammaticNames.getConstArray();
+ pName != aProgrammaticNames.getConstArray() + aProgrammaticNames.getLength();
+ ++pName, ++pDisplayName
+ )
+ {
+ ::utl::OConfigurationNode aRegistrationNode = m_aConfigurationRoot.openNode( *pName );
+ OSL_VERIFY( aRegistrationNode.getNodeValue( getNameNodeName() ) >>= *pDisplayName );
+
+ }
+
+ return aDisplayNames;
+ }
+
+ //--------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL DatabaseRegistrations::getDatabaseLocation( const ::rtl::OUString& _Name ) throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ ::utl::OConfigurationNode aNodeForName = impl_checkValidName_throw( _Name, true );
+
+ ::rtl::OUString sLocation;
+ OSL_VERIFY( aNodeForName.getNodeValue( getLocationNodeName() ) >>= sLocation );
+ sLocation = SvtPathOptions().SubstituteVariable( sLocation );
+
+ return sLocation;
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL DatabaseRegistrations::registerDatabaseLocation( const ::rtl::OUString& _Name, const ::rtl::OUString& _Location ) throw (IllegalArgumentException, ElementExistException, RuntimeException)
+ {
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+
+ // check
+ impl_checkValidLocation_throw( _Location );
+ ::utl::OConfigurationNode aDataSourceRegistration = impl_checkValidName_throw( _Name, false );
+
+ // register
+ aDataSourceRegistration.setNodeValue( getLocationNodeName(), makeAny( _Location ) );
+ m_aConfigurationRoot.commit();
+
+ // notify
+ DatabaseRegistrationEvent aEvent( *this, _Name, ::rtl::OUString(), _Location );
+ aGuard.clear();
+ m_aRegistrationListeners.notifyEach( &XDatabaseRegistrationsListener::registeredDatabaseLocation, aEvent );
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL DatabaseRegistrations::revokeDatabaseLocation( const ::rtl::OUString& _Name ) throw (IllegalArgumentException, NoSuchElementException, IllegalAccessException, RuntimeException)
+ {
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+
+ // check
+ ::utl::OConfigurationNode aNodeForName = impl_checkValidName_throw( _Name, true );
+
+ // obtain properties for notification
+ ::rtl::OUString sLocation;
+ OSL_VERIFY( aNodeForName.getNodeValue( getLocationNodeName() ) >>= sLocation );
+
+ // revoke
+ if ( aNodeForName.isReadonly()
+ || !m_aConfigurationRoot.removeNode( aNodeForName.getLocalName() )
+ )
+ throw IllegalAccessException( ::rtl::OUString(), *this );
+
+ m_aConfigurationRoot.commit();
+
+ // notify
+ DatabaseRegistrationEvent aEvent( *this, _Name, sLocation, ::rtl::OUString() );
+ aGuard.clear();
+ m_aRegistrationListeners.notifyEach( &XDatabaseRegistrationsListener::revokedDatabaseLocation, aEvent );
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL DatabaseRegistrations::changeDatabaseLocation( const ::rtl::OUString& _Name, const ::rtl::OUString& _NewLocation ) throw (IllegalArgumentException, NoSuchElementException, IllegalAccessException, RuntimeException)
+ {
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+
+ // check
+ impl_checkValidLocation_throw( _NewLocation );
+ ::utl::OConfigurationNode aDataSourceRegistration = impl_checkValidName_throw( _Name, true );
+
+ if ( aDataSourceRegistration.isReadonly() )
+ throw IllegalAccessException( ::rtl::OUString(), *this );
+
+ // obtain properties for notification
+ ::rtl::OUString sOldLocation;
+ OSL_VERIFY( aDataSourceRegistration.getNodeValue( getLocationNodeName() ) >>= sOldLocation );
+
+ // change
+ aDataSourceRegistration.setNodeValue( getLocationNodeName(), makeAny( _NewLocation ) );
+ m_aConfigurationRoot.commit();
+
+ // notify
+ DatabaseRegistrationEvent aEvent( *this, _Name, sOldLocation, _NewLocation );
+ aGuard.clear();
+ m_aRegistrationListeners.notifyEach( &XDatabaseRegistrationsListener::changedDatabaseLocation, aEvent );
+ }
+
+ //--------------------------------------------------------------------
+ ::sal_Bool SAL_CALL DatabaseRegistrations::isDatabaseRegistrationReadOnly( const ::rtl::OUString& _Name ) throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ ::utl::OConfigurationNode aDataSourceRegistration = impl_checkValidName_throw( _Name, true );
+ return aDataSourceRegistration.isReadonly();
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL DatabaseRegistrations::addDatabaseRegistrationsListener( const Reference< XDatabaseRegistrationsListener >& _Listener ) throw (RuntimeException)
+ {
+ if ( _Listener.is() )
+ m_aRegistrationListeners.addInterface( _Listener );
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL DatabaseRegistrations::removeDatabaseRegistrationsListener( const Reference< XDatabaseRegistrationsListener >& _Listener ) throw (RuntimeException)
+ {
+ if ( _Listener.is() )
+ m_aRegistrationListeners.removeInterface( _Listener );
+ }
+
+ //====================================================================
+ //= DatabaseRegistrations - factory
+ //====================================================================
+ Reference< XAggregation > createDataSourceRegistrations( const ::comphelper::ComponentContext& _rxContext )
+ {
+ return new DatabaseRegistrations( _rxContext );
+ }
+
+//........................................................................
+} // namespace dbaccess
+//........................................................................