summaryrefslogtreecommitdiff
path: root/dbaccess/source/core/dataaccess
diff options
context:
space:
mode:
Diffstat (limited to 'dbaccess/source/core/dataaccess')
-rw-r--r--dbaccess/source/core/dataaccess/ComponentDefinition.cxx301
-rw-r--r--dbaccess/source/core/dataaccess/ComponentDefinition.hxx184
-rw-r--r--dbaccess/source/core/dataaccess/ContentHelper.cxx673
-rw-r--r--dbaccess/source/core/dataaccess/ModelImpl.cxx1435
-rw-r--r--dbaccess/source/core/dataaccess/ModelImpl.hxx644
-rw-r--r--dbaccess/source/core/dataaccess/SharedConnection.cxx168
-rw-r--r--dbaccess/source/core/dataaccess/SharedConnection.hxx144
-rw-r--r--dbaccess/source/core/dataaccess/bookmarkcontainer.cxx371
-rw-r--r--dbaccess/source/core/dataaccess/bookmarkcontainer.hxx179
-rw-r--r--dbaccess/source/core/dataaccess/commandcontainer.cxx101
-rw-r--r--dbaccess/source/core/dataaccess/commandcontainer.hxx85
-rw-r--r--dbaccess/source/core/dataaccess/commanddefinition.cxx167
-rw-r--r--dbaccess/source/core/dataaccess/commanddefinition.hxx123
-rw-r--r--dbaccess/source/core/dataaccess/connection.cxx894
-rw-r--r--dbaccess/source/core/dataaccess/connection.hxx254
-rw-r--r--dbaccess/source/core/dataaccess/dataaccessdescriptor.cxx328
-rw-r--r--dbaccess/source/core/dataaccess/databasecontext.cxx770
-rw-r--r--dbaccess/source/core/dataaccess/databasecontext.hxx214
-rw-r--r--dbaccess/source/core/dataaccess/databasedocument.cxx2092
-rw-r--r--dbaccess/source/core/dataaccess/databasedocument.hxx709
-rw-r--r--dbaccess/source/core/dataaccess/databaseregistrations.cxx377
-rw-r--r--dbaccess/source/core/dataaccess/databaseregistrations.hxx50
-rw-r--r--dbaccess/source/core/dataaccess/datasource.cxx1418
-rw-r--r--dbaccess/source/core/dataaccess/datasource.hxx239
-rw-r--r--dbaccess/source/core/dataaccess/definitioncontainer.cxx681
-rw-r--r--dbaccess/source/core/dataaccess/documentcontainer.cxx784
-rw-r--r--dbaccess/source/core/dataaccess/documentcontainer.hxx146
-rw-r--r--dbaccess/source/core/dataaccess/documentdefinition.cxx2211
-rw-r--r--dbaccess/source/core/dataaccess/documentdefinition.hxx386
-rw-r--r--dbaccess/source/core/dataaccess/documenteventexecutor.cxx222
-rw-r--r--dbaccess/source/core/dataaccess/documenteventexecutor.hxx77
-rw-r--r--dbaccess/source/core/dataaccess/documenteventnotifier.cxx300
-rw-r--r--dbaccess/source/core/dataaccess/documenteventnotifier.hxx143
-rw-r--r--dbaccess/source/core/dataaccess/documentevents.cxx250
-rw-r--r--dbaccess/source/core/dataaccess/documentevents.hxx89
-rw-r--r--dbaccess/source/core/dataaccess/intercept.cxx446
-rw-r--r--dbaccess/source/core/dataaccess/intercept.hxx169
-rw-r--r--dbaccess/source/core/dataaccess/makefile.mk69
-rw-r--r--dbaccess/source/core/dataaccess/myucp_datasupplier.cxx393
-rw-r--r--dbaccess/source/core/dataaccess/myucp_datasupplier.hxx80
-rw-r--r--dbaccess/source/core/dataaccess/myucp_resultset.cxx99
-rw-r--r--dbaccess/source/core/dataaccess/myucp_resultset.hxx64
42 files changed, 18529 insertions, 0 deletions
diff --git a/dbaccess/source/core/dataaccess/ComponentDefinition.cxx b/dbaccess/source/core/dataaccess/ComponentDefinition.cxx
new file mode 100644
index 000000000000..df7a85434a91
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/ComponentDefinition.cxx
@@ -0,0 +1,301 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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"
+
+#include "ComponentDefinition.hxx"
+#include "apitools.hxx"
+#include "dbastrings.hrc"
+#include "module_dba.hxx"
+
+#include <tools/debug.hxx>
+#include <comphelper/sequence.hxx>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <comphelper/property.hxx>
+#include "definitioncolumn.hxx"
+#include <cppuhelper/implbase1.hxx>
+#include <comphelper/componentcontext.hxx>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::lang;
+
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::osl;
+using namespace ::comphelper;
+using namespace ::cppu;
+
+extern "C" void SAL_CALL createRegistryInfo_OComponentDefinition()
+{
+ static ::dba::OAutoRegistration< ::dbaccess::OComponentDefinition > aAutoRegistration;
+}
+
+namespace dbaccess
+{
+
+/// helper class for column property change events which holds the OComponentDefinition weak
+typedef ::cppu::WeakImplHelper1 < XPropertyChangeListener > TColumnPropertyListener_BASE;
+class OColumnPropertyListener : public TColumnPropertyListener_BASE
+{
+ OComponentDefinition* m_pComponent;
+
+ OColumnPropertyListener(const OColumnPropertyListener&);
+ void operator =(const OColumnPropertyListener&);
+protected:
+ virtual ~OColumnPropertyListener(){}
+public:
+ OColumnPropertyListener(OComponentDefinition* _pComponent) : m_pComponent(_pComponent){}
+ // XPropertyChangeListener
+ virtual void SAL_CALL propertyChange( const PropertyChangeEvent& /*_rEvent*/ ) throw (RuntimeException)
+ {
+ if ( m_pComponent )
+ m_pComponent->notifyDataSourceModified();
+ }
+ // XEventListener
+ virtual void SAL_CALL disposing( const EventObject& /*_rSource*/ ) throw (RuntimeException)
+ {
+ }
+ void clear() { m_pComponent = NULL; }
+};
+DBG_NAME(OComponentDefinition_Impl)
+OComponentDefinition_Impl::OComponentDefinition_Impl()
+{
+ DBG_CTOR(OComponentDefinition_Impl,NULL);
+}
+
+OComponentDefinition_Impl::~OComponentDefinition_Impl()
+{
+ DBG_DTOR(OComponentDefinition_Impl,NULL);
+}
+//==========================================================================
+//= OComponentDefinition
+//==========================================================================
+
+DBG_NAME(OComponentDefinition)
+
+void OComponentDefinition::registerProperties()
+{
+ m_xColumnPropertyListener = ::comphelper::ImplementationReference<OColumnPropertyListener,XPropertyChangeListener>(new OColumnPropertyListener(this));
+ OComponentDefinition_Impl& rDefinition( getDefinition() );
+ ODataSettings::registerPropertiesFor( &rDefinition );
+
+ registerProperty(PROPERTY_NAME, PROPERTY_ID_NAME, PropertyAttribute::BOUND | PropertyAttribute::READONLY|PropertyAttribute::CONSTRAINED,
+ &rDefinition.m_aProps.aTitle, ::getCppuType(&rDefinition.m_aProps.aTitle));
+
+ if ( m_bTable )
+ {
+ registerProperty(PROPERTY_SCHEMANAME, PROPERTY_ID_SCHEMANAME, PropertyAttribute::BOUND,
+ &rDefinition.m_sSchemaName, ::getCppuType(&rDefinition.m_sSchemaName));
+
+ registerProperty(PROPERTY_CATALOGNAME, PROPERTY_ID_CATALOGNAME, PropertyAttribute::BOUND,
+ &rDefinition.m_sCatalogName, ::getCppuType(&rDefinition.m_sCatalogName));
+ }
+}
+
+OComponentDefinition::OComponentDefinition(const Reference< XMultiServiceFactory >& _xORB
+ ,const Reference< XInterface >& _xParentContainer
+ ,const TContentPtr& _pImpl
+ ,sal_Bool _bTable)
+ :OContentHelper(_xORB,_xParentContainer,_pImpl)
+ ,ODataSettings(OContentHelper::rBHelper,!_bTable)
+ ,m_bTable(_bTable)
+{
+ DBG_CTOR(OComponentDefinition, NULL);
+ registerProperties();
+}
+
+OComponentDefinition::~OComponentDefinition()
+{
+ DBG_DTOR(OComponentDefinition, NULL);
+}
+
+
+OComponentDefinition::OComponentDefinition( const Reference< XInterface >& _rxContainer
+ ,const ::rtl::OUString& _rElementName
+ ,const Reference< XMultiServiceFactory >& _xORB
+ ,const TContentPtr& _pImpl
+ ,sal_Bool _bTable)
+ :OContentHelper(_xORB,_rxContainer,_pImpl)
+ ,ODataSettings(OContentHelper::rBHelper,!_bTable)
+ ,m_bTable(_bTable)
+{
+ DBG_CTOR(OComponentDefinition, NULL);
+ registerProperties();
+
+ m_pImpl->m_aProps.aTitle = _rElementName;
+ DBG_ASSERT(m_pImpl->m_aProps.aTitle.getLength() != 0, "OComponentDefinition::OComponentDefinition : invalid name !");
+}
+
+IMPLEMENT_IMPLEMENTATION_ID(OComponentDefinition);
+IMPLEMENT_GETTYPES3(OComponentDefinition,ODataSettings,OContentHelper,OComponentDefinition_BASE);
+IMPLEMENT_FORWARD_XINTERFACE3( OComponentDefinition,OContentHelper,ODataSettings,OComponentDefinition_BASE)
+
+::rtl::OUString OComponentDefinition::getImplementationName_static( ) throw(RuntimeException)
+{
+ return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.dba.OComponentDefinition"));
+}
+
+::rtl::OUString SAL_CALL OComponentDefinition::getImplementationName( ) throw(RuntimeException)
+{
+ return getImplementationName_static();
+}
+
+Sequence< ::rtl::OUString > OComponentDefinition::getSupportedServiceNames_static( ) throw(RuntimeException)
+{
+ Sequence< ::rtl::OUString > aServices(2);
+ aServices.getArray()[0] = SERVICE_SDB_TABLEDEFINITION;
+ aServices.getArray()[1] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.ucb.Content"));
+
+ return aServices;
+}
+
+Sequence< ::rtl::OUString > SAL_CALL OComponentDefinition::getSupportedServiceNames( ) throw(RuntimeException)
+{
+ return getSupportedServiceNames_static();
+}
+
+Reference< XInterface > OComponentDefinition::Create( const Reference< XComponentContext >& _rxContext )
+{
+ ::comphelper::ComponentContext aContext( _rxContext );
+ return *(new OComponentDefinition( aContext.getLegacyServiceFactory(), NULL, TContentPtr( new OComponentDefinition_Impl ) ) );
+}
+
+void SAL_CALL OComponentDefinition::disposing()
+{
+ OContentHelper::disposing();
+ if ( m_pColumns.get() )
+ m_pColumns->disposing();
+ m_xColumnPropertyListener->clear();
+ m_xColumnPropertyListener.dispose();
+}
+
+IPropertyArrayHelper& OComponentDefinition::getInfoHelper()
+{
+ return *getArrayHelper();
+}
+
+IPropertyArrayHelper* OComponentDefinition::createArrayHelper( ) const
+{
+ Sequence< Property > aProps;
+ describeProperties(aProps);
+ return new OPropertyArrayHelper(aProps);
+}
+
+Reference< XPropertySetInfo > SAL_CALL OComponentDefinition::getPropertySetInfo( ) throw(RuntimeException)
+{
+ Reference<XPropertySetInfo> xInfo( createPropertySetInfo( getInfoHelper() ) );
+ return xInfo;
+}
+
+::rtl::OUString OComponentDefinition::determineContentType() const
+{
+ return m_bTable
+ ? ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/vnd.org.openoffice.DatabaseTable" ) )
+ : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/vnd.org.openoffice.DatabaseCommandDefinition" ) );
+}
+
+Reference< XNameAccess> OComponentDefinition::getColumns() throw (RuntimeException)
+{
+ ::osl::MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OContentHelper::rBHelper.bDisposed);
+
+ if ( !m_pColumns.get() )
+ {
+ ::std::vector< ::rtl::OUString> aNames;
+
+ const OComponentDefinition_Impl& rDefinition( getDefinition() );
+ aNames.reserve( rDefinition.size() );
+
+ OComponentDefinition_Impl::const_iterator aIter = rDefinition.begin();
+ OComponentDefinition_Impl::const_iterator aEnd = rDefinition.end();
+ for ( ; aIter != aEnd; ++aIter )
+ aNames.push_back( aIter->first );
+
+ m_pColumns.reset( new OColumns( *this, m_aMutex, sal_True, aNames, this, NULL, sal_True, sal_False, sal_False ) );
+ m_pColumns->setParent( *this );
+ }
+ return m_pColumns.get();
+}
+
+OColumn* OComponentDefinition::createColumn(const ::rtl::OUString& _rName) const
+{
+ const OComponentDefinition_Impl& rDefinition( getDefinition() );
+ OComponentDefinition_Impl::const_iterator aFind = rDefinition.find( _rName );
+ if ( aFind != rDefinition.end() )
+ {
+ aFind->second->addPropertyChangeListener(::rtl::OUString(),m_xColumnPropertyListener.getRef());
+ return new OTableColumnWrapper( aFind->second, aFind->second, true );
+ }
+ OSL_ENSURE( false, "OComponentDefinition::createColumn: is this a valid case?" );
+ // This here is the last place creating a OTableColumn, and somehow /me thinks it is not needed ...
+ return new OTableColumn( _rName );
+}
+
+Reference< XPropertySet > OComponentDefinition::createColumnDescriptor()
+{
+ return new OTableColumnDescriptor( true );
+}
+
+void OComponentDefinition::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue) throw (Exception)
+{
+ ODataSettings::setFastPropertyValue_NoBroadcast(nHandle,rValue);
+ notifyDataSourceModified();
+}
+
+void OComponentDefinition::columnDropped(const ::rtl::OUString& _sName)
+{
+ getDefinition().erase( _sName );
+ notifyDataSourceModified();
+}
+
+void OComponentDefinition::columnAppended( const Reference< XPropertySet >& _rxSourceDescriptor )
+{
+ ::rtl::OUString sName;
+ _rxSourceDescriptor->getPropertyValue( PROPERTY_NAME ) >>= sName;
+
+ Reference<XPropertySet> xColDesc = new OTableColumnDescriptor( true );
+ ::comphelper::copyProperties( _rxSourceDescriptor, xColDesc );
+ getDefinition().insert( sName, xColDesc );
+
+ // formerly, here was a setParent at the xColDesc. The parent used was an adapter (ChildHelper_Impl)
+ // which held another XChild weak, and forwarded all getParent requests to this other XChild.
+ // m_pColumns was used for this. This was nonsense, since m_pColumns dies when our instance dies,
+ // but xColDesc will live longer than this. So effectively, the setParent call was pretty useless.
+ //
+ // The intention for this parenting was that the column descriptor is able to find the data source,
+ // by traveling up the parent hierachy until there's an XDataSource. This didn't work (which
+ // for instance causes #i65023#). We need another way to properly ensure this.
+
+ notifyDataSourceModified();
+}
+
+} // namespace dbaccess
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/ComponentDefinition.hxx b/dbaccess/source/core/dataaccess/ComponentDefinition.hxx
new file mode 100644
index 000000000000..6da15cd19fbb
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/ComponentDefinition.hxx
@@ -0,0 +1,184 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef DBA_COREDATAACESS_COMPONENTDEFINITION_HXX
+#define DBA_COREDATAACESS_COMPONENTDEFINITION_HXX
+
+#include "commandbase.hxx"
+#include <comphelper/propertycontainer.hxx>
+#include <com/sun/star/sdbcx/XRename.hpp>
+#include <cppuhelper/implbase1.hxx>
+#include <comphelper/proparrhlp.hxx>
+#include "datasettings.hxx"
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
+#include <com/sun/star/beans/XPropertyChangeListener.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include "ContentHelper.hxx"
+#include "apitools.hxx"
+#include <column.hxx>
+#include <comphelper/implementationreference.hxx>
+
+#include <memory>
+//........................................................................
+namespace dbaccess
+{
+//........................................................................
+
+ typedef ::cppu::ImplHelper1< ::com::sun::star::sdbcx::XColumnsSupplier > OComponentDefinition_BASE;
+
+ class OComponentDefinition_Impl : public OContentHelper_Impl
+ ,public ODataSettings_Base
+ {
+ public:
+ typedef ::std::map < ::rtl::OUString
+ , ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
+ > Columns;
+ typedef Columns::iterator iterator;
+ typedef Columns::const_iterator const_iterator;
+
+ private:
+ Columns m_aColumns;
+
+ public:
+ ::rtl::OUString m_sSchemaName;
+ ::rtl::OUString m_sCatalogName;
+
+ public:
+ OComponentDefinition_Impl();
+ virtual ~OComponentDefinition_Impl();
+
+ inline size_t size() const { return m_aColumns.size(); }
+
+ inline const_iterator begin() const { return m_aColumns.begin(); }
+ inline const_iterator end() const { return m_aColumns.end(); }
+
+ inline const_iterator find( const ::rtl::OUString& _rName ) const { return m_aColumns.find( _rName ); }
+
+ inline void erase( const ::rtl::OUString& _rName ) { m_aColumns.erase( _rName ); }
+
+ inline void insert( const ::rtl::OUString& _rName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxColumn )
+ {
+ OSL_PRECOND( m_aColumns.find( _rName ) == m_aColumns.end(), "OComponentDefinition_Impl::insert: there's already an element with this name!" );
+ m_aColumns.insert( Columns::value_type( _rName, _rxColumn ) );
+ }
+ };
+
+class OColumnPropertyListener;
+//=========================================================================
+//= OComponentDefinition - a database "document" which describes a query
+//=========================================================================
+class OComponentDefinition :public OContentHelper
+ ,public ODataSettings
+ ,public IColumnFactory
+ ,public OComponentDefinition_BASE
+ ,public ::comphelper::OPropertyArrayUsageHelper< OComponentDefinition >
+{
+ OComponentDefinition();
+
+protected:
+ ::std::auto_ptr< OColumns > m_pColumns;
+ ::comphelper::ImplementationReference< OColumnPropertyListener,::com::sun::star::beans::XPropertyChangeListener>
+ m_xColumnPropertyListener;
+ sal_Bool m_bTable;
+
+ virtual ~OComponentDefinition();
+ virtual void SAL_CALL disposing();
+
+
+protected:
+ OComponentDefinition(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&
+ ,const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _xParentContainer
+ ,const TContentPtr& _pImpl
+ ,sal_Bool _bTable = sal_True);
+
+ const OComponentDefinition_Impl& getDefinition() const { return dynamic_cast< const OComponentDefinition_Impl& >( *m_pImpl.get() ); }
+ OComponentDefinition_Impl& getDefinition() { return dynamic_cast< OComponentDefinition_Impl& >( *m_pImpl.get() ); }
+public:
+
+ OComponentDefinition(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxContainer
+ ,const ::rtl::OUString& _rElementName
+ ,const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&
+ ,const TContentPtr& _pImpl
+ ,sal_Bool _bTable = sal_True
+ );
+
+// com::sun::star::lang::XTypeProvider
+ DECLARE_TYPEPROVIDER( );
+
+// ::com::sun::star::uno::XInterface
+ DECLARE_XINTERFACE( )
+
+// ::com::sun::star::lang::XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException);
+
+ static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_static(void) throw( ::com::sun::star::uno::RuntimeException );
+ static ::rtl::OUString getImplementationName_static(void) throw( ::com::sun::star::uno::RuntimeException );
+ static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL
+ Create(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >&);
+
+// ::com::sun::star::beans::XPropertySet
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) throw(::com::sun::star::uno::RuntimeException);
+
+ // XColumnsSupplier
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL getColumns( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // OPropertySetHelper
+ virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
+
+ // IColumnFactory
+ virtual OColumn* createColumn(const ::rtl::OUString& _rName) const;
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > createColumnDescriptor();
+ virtual void columnAppended( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxSourceDescriptor );
+ virtual void columnDropped(const ::rtl::OUString& _sName);
+ virtual void notifyDataSourceModified() { OContentHelper::notifyDataSourceModified(); }
+
+protected:
+// OPropertyArrayUsageHelper
+ virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;
+
+ virtual void SAL_CALL setFastPropertyValue_NoBroadcast(
+ sal_Int32 nHandle,
+ const ::com::sun::star::uno::Any& rValue) throw (::com::sun::star::uno::Exception);
+
+ // OContentHelper overridables
+ virtual ::rtl::OUString determineContentType() const;
+
+private:
+ void registerProperties();
+};
+
+//........................................................................
+} // namespace dbaccess
+//........................................................................
+
+#endif // DBA_COREDATAACESS_COMPONENTDEFINITION_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/ContentHelper.cxx b/dbaccess/source/core/dataaccess/ContentHelper.cxx
new file mode 100644
index 000000000000..da4e3c271a69
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/ContentHelper.cxx
@@ -0,0 +1,673 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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"
+#include "ContentHelper.hxx"
+#include <ucbhelper/cancelcommandexecution.hxx>
+#include <comphelper/property.hxx>
+#include <com/sun/star/ucb/UnsupportedCommandException.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/lang/IllegalAccessException.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XActiveDataSink.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <ucbhelper/propertyvalueset.hxx>
+#include <ucbhelper/contentidentifier.hxx>
+#include "myucp_resultset.hxx"
+#include <com/sun/star/container/XNameContainer.hpp>
+#include "sdbcoretools.hxx"
+#include "dbastrings.hrc"
+#include <tools/debug.hxx>
+
+
+namespace dbaccess
+{
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::embed;
+using namespace ::com::sun::star::container;
+using namespace ::comphelper;
+using namespace ::cppu;
+
+DBG_NAME(OContentHelper_Impl)
+OContentHelper_Impl::OContentHelper_Impl()
+{
+ DBG_CTOR(OContentHelper_Impl,NULL);
+}
+
+OContentHelper_Impl::~OContentHelper_Impl()
+{
+ DBG_DTOR(OContentHelper_Impl,NULL);
+}
+
+OContentHelper::OContentHelper(const Reference< XMultiServiceFactory >& _xORB
+ ,const Reference< XInterface >& _xParentContainer
+ ,const TContentPtr& _pImpl)
+ : OContentHelper_COMPBASE(m_aMutex)
+ ,m_aContentListeners(m_aMutex)
+ ,m_aPropertyChangeListeners(m_aMutex)
+ ,m_xParentContainer(_xParentContainer)
+ ,m_aContext( _xORB )
+ ,m_aErrorHelper( m_aContext )
+ ,m_pImpl(_pImpl)
+ ,m_nCommandId(0)
+{
+}
+
+void SAL_CALL OContentHelper::disposing()
+{
+ ::osl::MutexGuard aGuard(m_aMutex);
+
+ // say our listeners goobye
+ EventObject aEvt(*this);
+ m_aContentListeners.disposeAndClear(aEvt);
+
+ m_xParentContainer = NULL;
+}
+
+IMPLEMENT_SERVICE_INFO1(OContentHelper,"com.sun.star.comp.sdb.Content","com.sun.star.ucb.Content");
+IMPLEMENT_IMPLEMENTATION_ID(OContentHelper)
+
+// XContent
+Reference< XContentIdentifier > SAL_CALL OContentHelper::getIdentifier( ) throw (RuntimeException)
+{
+ ::osl::MutexGuard aGuard(m_aMutex);
+ ::rtl::OUStringBuffer aIdentifier;
+ aIdentifier.appendAscii( "private:" );
+ aIdentifier.append( impl_getHierarchicalName( true ) );
+ return new ::ucbhelper::ContentIdentifier( m_aContext.getLegacyServiceFactory(), aIdentifier.makeStringAndClear() );
+}
+
+::rtl::OUString OContentHelper::impl_getHierarchicalName( bool _includingRootContainer ) const
+{
+ ::rtl::OUStringBuffer aHierarchicalName( m_pImpl->m_aProps.aTitle );
+ Reference< XInterface > xParent = m_xParentContainer;
+ while( xParent.is() )
+ {
+ Reference<XPropertySet> xProp( xParent, UNO_QUERY );
+ Reference< XChild > xChild( xParent, UNO_QUERY );
+ xParent.set( xChild.is() ? xChild->getParent() : Reference< XInterface >(), UNO_QUERY );
+ if ( xProp.is() && xParent.is() )
+ {
+ ::rtl::OUString sName;
+ xProp->getPropertyValue( PROPERTY_NAME ) >>= sName;
+
+ ::rtl::OUString sPrevious = aHierarchicalName.makeStringAndClear();
+ aHierarchicalName.append( sName );
+ aHierarchicalName.append( sal_Unicode( '/' ) );
+ aHierarchicalName.append( sPrevious );
+ }
+ }
+ ::rtl::OUString sHierarchicalName( aHierarchicalName.makeStringAndClear() );
+ if ( !_includingRootContainer )
+ sHierarchicalName = sHierarchicalName.copy( sHierarchicalName.indexOf( '/' ) + 1 );
+ return sHierarchicalName;
+}
+
+::rtl::OUString SAL_CALL OContentHelper::getContentType() throw (RuntimeException)
+{
+ ::osl::MutexGuard aGuard(m_aMutex);
+
+ if ( !m_pImpl->m_aProps.aContentType )
+ { // content type not yet retrieved
+ m_pImpl->m_aProps.aContentType.reset( determineContentType() );
+ }
+
+ return *m_pImpl->m_aProps.aContentType;
+}
+
+void SAL_CALL OContentHelper::addContentEventListener( const Reference< XContentEventListener >& _rxListener ) throw (RuntimeException)
+{
+ ::osl::MutexGuard aGuard(m_aMutex);
+ if ( _rxListener.is() )
+ m_aContentListeners.addInterface(_rxListener);
+}
+
+void SAL_CALL OContentHelper::removeContentEventListener( const Reference< XContentEventListener >& _rxListener ) throw (RuntimeException)
+{
+ ::osl::MutexGuard aGuard(m_aMutex);
+ if (_rxListener.is())
+ m_aContentListeners.removeInterface(_rxListener);
+}
+
+// XCommandProcessor
+sal_Int32 SAL_CALL OContentHelper::createCommandIdentifier( ) throw (RuntimeException)
+{
+ ::osl::MutexGuard aGuard(m_aMutex);
+ // Just increase counter on every call to generate an identifier.
+ return ++m_nCommandId;
+}
+
+Any SAL_CALL OContentHelper::execute( const Command& aCommand, sal_Int32 /*CommandId*/, const Reference< XCommandEnvironment >& Environment ) throw (Exception, CommandAbortedException, RuntimeException)
+{
+ Any aRet;
+ if ( aCommand.Name.compareToAscii( "getPropertyValues" ) == 0 )
+ {
+ //////////////////////////////////////////////////////////////////
+ // getPropertyValues
+ //////////////////////////////////////////////////////////////////
+
+ Sequence< Property > Properties;
+ if ( !( aCommand.Argument >>= Properties ) )
+ {
+ OSL_ENSURE( sal_False, "Wrong argument type!" );
+ ucbhelper::cancelCommandExecution(
+ makeAny( IllegalArgumentException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+ aRet <<= getPropertyValues( Properties);
+ }
+ else if ( aCommand.Name.compareToAscii( "setPropertyValues" ) == 0 )
+ {
+ //////////////////////////////////////////////////////////////////
+ // setPropertyValues
+ //////////////////////////////////////////////////////////////////
+
+ Sequence< PropertyValue > aProperties;
+ if ( !( aCommand.Argument >>= aProperties ) )
+ {
+ OSL_ENSURE( sal_False, "Wrong argument type!" );
+ ucbhelper::cancelCommandExecution(
+ makeAny( IllegalArgumentException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ if ( !aProperties.getLength() )
+ {
+ OSL_ENSURE( sal_False, "No properties!" );
+ ucbhelper::cancelCommandExecution(
+ makeAny( IllegalArgumentException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ aRet <<= setPropertyValues( aProperties, Environment );
+ }
+ else if ( aCommand.Name.compareToAscii( "getPropertySetInfo" ) == 0 )
+ {
+ //////////////////////////////////////////////////////////////////
+ // getPropertySetInfo
+ //////////////////////////////////////////////////////////////////
+
+ Reference<XPropertySet> xProp(*this,UNO_QUERY);
+ if ( xProp.is() )
+ aRet <<= xProp->getPropertySetInfo();
+ // aRet <<= getPropertySetInfo(); // TODO
+ }
+ else
+ {
+ //////////////////////////////////////////////////////////////////
+ // Unsupported command
+ //////////////////////////////////////////////////////////////////
+
+ OSL_ENSURE( sal_False, "Content::execute - unsupported command!" );
+
+ ucbhelper::cancelCommandExecution(
+ makeAny( UnsupportedCommandException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ Environment );
+ // Unreachable
+ }
+
+ return aRet;
+}
+
+void SAL_CALL OContentHelper::abort( sal_Int32 /*CommandId*/ ) throw (RuntimeException)
+{
+}
+
+// XPropertiesChangeNotifier
+void SAL_CALL OContentHelper::addPropertiesChangeListener( const Sequence< ::rtl::OUString >& PropertyNames, const Reference< XPropertiesChangeListener >& Listener ) throw (RuntimeException)
+{
+ ::osl::MutexGuard aGuard(m_aMutex);
+ sal_Int32 nCount = PropertyNames.getLength();
+ if ( !nCount )
+ {
+ // Note: An empty sequence means a listener for "all" properties.
+ m_aPropertyChangeListeners.addInterface(::rtl::OUString(), Listener );
+ }
+ else
+ {
+ const ::rtl::OUString* pSeq = PropertyNames.getConstArray();
+
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ const ::rtl::OUString& rName = pSeq[ n ];
+ if ( rName.getLength() )
+ m_aPropertyChangeListeners.addInterface(rName, Listener );
+ }
+ }
+}
+
+void SAL_CALL OContentHelper::removePropertiesChangeListener( const Sequence< ::rtl::OUString >& PropertyNames, const Reference< XPropertiesChangeListener >& Listener ) throw (RuntimeException)
+{
+ ::osl::MutexGuard aGuard(m_aMutex);
+ sal_Int32 nCount = PropertyNames.getLength();
+ if ( !nCount )
+ {
+ // Note: An empty sequence means a listener for "all" properties.
+ m_aPropertyChangeListeners.removeInterface( ::rtl::OUString(), Listener );
+ }
+ else
+ {
+ const ::rtl::OUString* pSeq = PropertyNames.getConstArray();
+
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ const ::rtl::OUString& rName = pSeq[ n ];
+ if ( rName.getLength() )
+ m_aPropertyChangeListeners.removeInterface( rName, Listener );
+ }
+ }
+}
+
+// XPropertyContainer
+void SAL_CALL OContentHelper::addProperty( const ::rtl::OUString& /*Name*/, sal_Int16 /*Attributes*/, const Any& /*DefaultValue*/ ) throw (PropertyExistException, IllegalTypeException, IllegalArgumentException, RuntimeException)
+{
+ DBG_ERROR( "OContentHelper::addProperty: not implemented!" );
+}
+
+void SAL_CALL OContentHelper::removeProperty( const ::rtl::OUString& /*Name*/ ) throw (UnknownPropertyException, NotRemoveableException, RuntimeException)
+{
+ DBG_ERROR( "OContentHelper::removeProperty: not implemented!" );
+}
+
+// XInitialization
+void SAL_CALL OContentHelper::initialize( const Sequence< Any >& _aArguments ) throw(Exception, RuntimeException)
+{
+ const Any* pBegin = _aArguments.getConstArray();
+ const Any* pEnd = pBegin + _aArguments.getLength();
+ PropertyValue aValue;;
+ for(;pBegin != pEnd;++pBegin)
+ {
+ *pBegin >>= aValue;
+ if ( aValue.Name.equalsAscii("Parent") )
+ {
+ m_xParentContainer.set(aValue.Value,UNO_QUERY);
+ }
+ else if ( aValue.Name.equalsAscii(PROPERTY_NAME) )
+ {
+ aValue.Value >>= m_pImpl->m_aProps.aTitle;
+ }
+ else if ( aValue.Name.equalsAscii(PROPERTY_PERSISTENT_NAME) )
+ {
+ aValue.Value >>= m_pImpl->m_aProps.sPersistentName;
+ }
+ }
+}
+
+Sequence< Any > OContentHelper::setPropertyValues(const Sequence< PropertyValue >& rValues,const Reference< XCommandEnvironment >& /*xEnv*/ )
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+
+ Sequence< Any > aRet( rValues.getLength() );
+ Sequence< PropertyChangeEvent > aChanges( rValues.getLength() );
+ sal_Int32 nChanged = 0;
+
+ PropertyChangeEvent aEvent;
+ aEvent.Source = static_cast< cppu::OWeakObject * >( this );
+ aEvent.Further = sal_False;
+ aEvent.PropertyHandle = -1;
+
+ const PropertyValue* pValues = rValues.getConstArray();
+ sal_Int32 nCount = rValues.getLength();
+
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ const PropertyValue& rValue = pValues[ n ];
+
+ if ( rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) )
+ {
+ // Read-only property!
+ aRet[ n ] <<= IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else if ( rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) )
+ {
+ // Read-only property!
+ aRet[ n ] <<= IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else if ( rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) )
+ {
+ // Read-only property!
+ aRet[ n ] <<= IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else if ( rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
+ {
+ rtl::OUString aNewValue;
+ if ( rValue.Value >>= aNewValue )
+ {
+ if ( aNewValue != m_pImpl->m_aProps.aTitle )
+ {
+ aEvent.PropertyName = rValue.Name;
+ aEvent.OldValue = makeAny( m_pImpl->m_aProps.aTitle );
+
+ try
+ {
+ impl_rename_throw( aNewValue ,false);
+ OSL_ENSURE( m_pImpl->m_aProps.aTitle == aNewValue, "OContentHelper::setPropertyValues('Title'): rename did not work!" );
+
+ aEvent.NewValue = makeAny( aNewValue );
+ aChanges.getArray()[ nChanged ] = aEvent;
+ nChanged++;
+ }
+ catch( const Exception& )
+ {
+ OSL_ENSURE( sal_False, "OContentHelper::setPropertyValues('Title'): caught an exception while renaming!" );
+ }
+ }
+ else
+ {
+ // Old value equals new value. No error!
+ }
+ }
+ else
+ {
+ aRet[ n ] <<= IllegalTypeException(
+ rtl::OUString::createFromAscii(
+ "Property value has wrong type!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ }
+
+ else
+ {
+ aRet[ n ] <<= Exception(
+ rtl::OUString::createFromAscii(
+ "No property set for storing the value!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ }
+
+ if ( nChanged > 0 )
+ {
+ // @@@ Save changes.
+// storeData();
+
+ notifyDataSourceModified();
+ aGuard.clear();
+ aChanges.realloc( nChanged );
+ notifyPropertiesChange( aChanges );
+ }
+
+ return aRet;
+}
+
+//=========================================================================
+// static
+Reference< XRow > OContentHelper::getPropertyValues( const Sequence< Property >& rProperties)
+{
+ // Note: Empty sequence means "get values of all supported properties".
+
+ rtl::Reference< ::ucbhelper::PropertyValueSet > xRow = new ::ucbhelper::PropertyValueSet( m_aContext.getLegacyServiceFactory() );
+
+ sal_Int32 nCount = rProperties.getLength();
+ if ( nCount )
+ {
+ const Property* pProps = rProperties.getConstArray();
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ const Property& rProp = pProps[ n ];
+
+ // Process Core properties.
+
+ if ( rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) )
+ {
+ xRow->appendString ( rProp, getContentType() );
+ }
+ else if ( rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
+ {
+ xRow->appendString ( rProp, m_pImpl->m_aProps.aTitle );
+ }
+ else if ( rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) )
+ {
+ xRow->appendBoolean( rProp, m_pImpl->m_aProps.bIsDocument );
+ }
+ else if ( rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) )
+ {
+ xRow->appendBoolean( rProp, m_pImpl->m_aProps.bIsFolder );
+ }
+ else
+ xRow->appendVoid(rProp);
+ }
+ }
+ else
+ {
+ // Append all Core Properties.
+ xRow->appendString (
+ Property( rtl::OUString::createFromAscii( "ContentType" ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ PropertyAttribute::BOUND
+ | PropertyAttribute::READONLY ),
+ getContentType() );
+ xRow->appendString (
+ Property( rtl::OUString::createFromAscii( "Title" ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ PropertyAttribute::BOUND ),
+ m_pImpl->m_aProps.aTitle );
+ xRow->appendBoolean(
+ Property( rtl::OUString::createFromAscii( "IsDocument" ),
+ -1,
+ getCppuBooleanType(),
+ PropertyAttribute::BOUND
+ | PropertyAttribute::READONLY ),
+ m_pImpl->m_aProps.bIsDocument );
+ xRow->appendBoolean(
+ Property( rtl::OUString::createFromAscii( "IsFolder" ),
+ -1,
+ getCppuBooleanType(),
+ PropertyAttribute::BOUND
+ | PropertyAttribute::READONLY ),
+ m_pImpl->m_aProps.bIsFolder );
+
+ // @@@ Append other properties supported directly.
+ }
+
+ return Reference< XRow >( xRow.get() );
+}
+
+void OContentHelper::notifyPropertiesChange( const Sequence< PropertyChangeEvent >& evt ) const
+{
+
+ sal_Int32 nCount = evt.getLength();
+ if ( nCount )
+ {
+ // First, notify listeners interested in changes of every property.
+ OInterfaceContainerHelper* pAllPropsContainer = m_aPropertyChangeListeners.getContainer( ::rtl::OUString() );
+ if ( pAllPropsContainer )
+ {
+ OInterfaceIteratorHelper aIter( *pAllPropsContainer );
+ while ( aIter.hasMoreElements() )
+ {
+ // Propagate event.
+ Reference< XPropertiesChangeListener > xListener( aIter.next(), UNO_QUERY );
+ if ( xListener.is() )
+ xListener->propertiesChange( evt );
+ }
+ }
+
+ typedef Sequence< PropertyChangeEvent > PropertyEventSequence;
+ typedef ::std::map< XPropertiesChangeListener*, PropertyEventSequence* > PropertiesEventListenerMap;
+ PropertiesEventListenerMap aListeners;
+
+ const PropertyChangeEvent* propertyChangeEvent = evt.getConstArray();
+
+ for ( sal_Int32 n = 0; n < nCount; ++n, ++propertyChangeEvent )
+ {
+ const PropertyChangeEvent& rEvent = *propertyChangeEvent;
+ const ::rtl::OUString& rName = rEvent.PropertyName;
+
+ OInterfaceContainerHelper* pPropsContainer = m_aPropertyChangeListeners.getContainer( rName );
+ if ( pPropsContainer )
+ {
+ OInterfaceIteratorHelper aIter( *pPropsContainer );
+ while ( aIter.hasMoreElements() )
+ {
+ PropertyEventSequence* propertyEvents = NULL;
+
+ XPropertiesChangeListener* pListener = static_cast< XPropertiesChangeListener * >( aIter.next() );
+ PropertiesEventListenerMap::iterator it = aListeners.find( pListener );
+ if ( it == aListeners.end() )
+ {
+ // Not in map - create and insert new entry.
+ propertyEvents = new PropertyEventSequence( nCount );
+ aListeners[ pListener ] = propertyEvents;
+ }
+ else
+ propertyEvents = (*it).second;
+
+ if ( propertyEvents )
+ (*propertyEvents)[n] = rEvent;
+ }
+ }
+ }
+
+ // Notify listeners.
+ PropertiesEventListenerMap::iterator it = aListeners.begin();
+ while ( !aListeners.empty() )
+ {
+ XPropertiesChangeListener* pListener =
+ static_cast< XPropertiesChangeListener * >( (*it).first );
+ PropertyEventSequence* pSeq = (*it).second;
+
+ // Remove current element.
+ aListeners.erase( it );
+
+ // Propagate event.
+ pListener->propertiesChange( *pSeq );
+
+ delete pSeq;
+
+ it = aListeners.begin();
+ }
+ }
+}
+
+// com::sun::star::lang::XUnoTunnel
+sal_Int64 OContentHelper::getSomething( const Sequence< sal_Int8 > & rId ) throw (RuntimeException)
+{
+ if (rId.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(), rId.getConstArray(), 16 ) )
+ return reinterpret_cast<sal_Int64>(this);
+
+ return 0;
+}
+
+OContentHelper* OContentHelper::getImplementation( const Reference< XInterface >& _rxComponent )
+{
+ OContentHelper* pContent( NULL );
+
+ Reference< XUnoTunnel > xUnoTunnel( _rxComponent, UNO_QUERY );
+ if ( xUnoTunnel.is() )
+ pContent = reinterpret_cast< OContentHelper* >( xUnoTunnel->getSomething( getUnoTunnelImplementationId() ) );
+
+ return pContent;
+}
+
+Reference< XInterface > SAL_CALL OContentHelper::getParent( ) throw (RuntimeException)
+{
+ ::osl::MutexGuard aGuard(m_aMutex);
+ return m_xParentContainer;
+}
+
+void SAL_CALL OContentHelper::setParent( const Reference< XInterface >& _xParent ) throw (NoSupportException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard(m_aMutex);
+ m_xParentContainer = _xParent;
+}
+
+void OContentHelper::impl_rename_throw(const ::rtl::OUString& _sNewName,bool _bNotify )
+{
+ osl::ClearableGuard< osl::Mutex > aGuard(m_aMutex);
+ if ( _sNewName.equals( m_pImpl->m_aProps.aTitle ) )
+ return;
+ try
+ {
+ Sequence< PropertyChangeEvent > aChanges( 1 );
+
+ aChanges[0].Source = static_cast< cppu::OWeakObject * >( this );
+ aChanges[0].Further = sal_False;
+ aChanges[0].PropertyName = PROPERTY_NAME;
+ aChanges[0].PropertyHandle = PROPERTY_ID_NAME;
+ aChanges[0].OldValue <<= m_pImpl->m_aProps.aTitle;
+ aChanges[0].NewValue <<= _sNewName;
+
+ aGuard.clear();
+
+ m_pImpl->m_aProps.aTitle = _sNewName;
+ if ( _bNotify )
+ notifyPropertiesChange( aChanges );
+ notifyDataSourceModified();
+ }
+ catch(const PropertyVetoException&)
+ {
+ throw ElementExistException(_sNewName,*this);
+ }
+}
+
+void SAL_CALL OContentHelper::rename( const ::rtl::OUString& newName ) throw (SQLException, ElementExistException, RuntimeException)
+{
+
+ impl_rename_throw(newName);
+
+}
+
+void OContentHelper::notifyDataSourceModified()
+{
+ ::dbaccess::notifyDataSourceModified(m_xParentContainer,sal_True);
+}
+
+} // namespace dbaccess
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/ModelImpl.cxx b/dbaccess/source/core/dataaccess/ModelImpl.cxx
new file mode 100644
index 000000000000..d3de75af3d53
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/ModelImpl.cxx
@@ -0,0 +1,1435 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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"
+
+#include "commandcontainer.hxx"
+#include "connection.hxx"
+#include "core_resource.hrc"
+#include "core_resource.hxx"
+#include "databasecontext.hxx"
+#include "databasedocument.hxx"
+#include "datasource.hxx"
+#include "dbastrings.hrc"
+#include "ModelImpl.hxx"
+#include "userinformation.hxx"
+#include "sdbcoretools.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/container/XSet.hpp>
+#include <com/sun/star/document/MacroExecMode.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/embed/XTransactionBroadcaster.hpp>
+#include <com/sun/star/sdb/BooleanComparisonMode.hpp>
+#include <com/sun/star/script/DocumentScriptLibraryContainer.hpp>
+#include <com/sun/star/script/DocumentDialogLibraryContainer.hpp>
+#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
+#include <com/sun/star/form/XLoadable.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/interaction.hxx>
+#include <comphelper/mediadescriptor.hxx>
+#include <comphelper/seqstream.hxx>
+#include <comphelper/sequence.hxx>
+#include <connectivity/dbexception.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <rtl/digest.h>
+#include <sfx2/signaturestate.hxx>
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+#include <tools/errcode.hxx>
+#include <tools/urlobj.hxx>
+#include <unotools/sharedunocomponent.hxx>
+
+#include <algorithm>
+
+using namespace ::com::sun::star::document;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::embed;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::task;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::view;
+using namespace ::com::sun::star::task;
+using namespace ::com::sun::star::reflection;
+using namespace ::com::sun::star::script;
+using namespace ::cppu;
+using namespace ::osl;
+using namespace ::dbtools;
+using namespace ::comphelper;
+namespace css = ::com::sun::star;
+
+namespace dbaccess
+{
+
+//============================================================
+//= VosMutexFacade
+//============================================================
+VosMutexFacade::VosMutexFacade( ::osl::Mutex& _rMutex )
+ :m_rMutex( _rMutex )
+{
+}
+
+void SAL_CALL VosMutexFacade::acquire()
+{
+ m_rMutex.acquire();
+}
+
+sal_Bool SAL_CALL VosMutexFacade::tryToAcquire()
+{
+ return m_rMutex.tryToAcquire();
+}
+
+void SAL_CALL VosMutexFacade::release()
+{
+ m_rMutex.release();
+}
+
+//============================================================
+//= DocumentStorageAccess
+//============================================================
+DBG_NAME( DocumentStorageAccess )
+class DocumentStorageAccess : public ::cppu::WeakImplHelper2< XDocumentSubStorageSupplier
+ , XTransactionListener >
+{
+ typedef ::std::map< ::rtl::OUString, Reference< XStorage > > NamedStorages;
+
+ ::osl::Mutex m_aMutex;
+ /// all sub storages which we ever gave to the outer world
+ NamedStorages m_aExposedStorages;
+ ODatabaseModelImpl* m_pModelImplementation;
+ bool m_bPropagateCommitToRoot;
+ bool m_bDisposingSubStorages;
+
+public:
+ DocumentStorageAccess( ODatabaseModelImpl& _rModelImplementation )
+ :m_pModelImplementation( &_rModelImplementation )
+ ,m_bPropagateCommitToRoot( true )
+ ,m_bDisposingSubStorages( false )
+ {
+ DBG_CTOR( DocumentStorageAccess, NULL );
+ }
+
+protected:
+ ~DocumentStorageAccess()
+ {
+ DBG_DTOR( DocumentStorageAccess, NULL );
+ }
+
+public:
+ void dispose();
+
+ // XDocumentSubStorageSupplier
+ virtual Reference< XStorage > SAL_CALL getDocumentSubStorage( const ::rtl::OUString& aStorageName, ::sal_Int32 _nMode ) throw (RuntimeException);
+ virtual Sequence< ::rtl::OUString > SAL_CALL getDocumentSubStoragesNames( ) throw (IOException, RuntimeException);
+
+ // XTransactionListener
+ virtual void SAL_CALL preCommit( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL commited( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL preRevert( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL reverted( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);
+
+ /// disposes all storages managed by this instance
+ void disposeStorages();
+
+ /// disposes all known sub storages
+ void commitStorages() SAL_THROW(( IOException, RuntimeException ));
+
+ /// commits the dedicated "database" storage
+ bool commitEmbeddedStorage( bool _bPreventRootCommits );
+
+private:
+ /** opens the sub storage with the given name, in the given mode
+ */
+ Reference< XStorage > impl_openSubStorage_nothrow( const ::rtl::OUString& _rStorageName, sal_Int32 _nMode );
+
+ void impl_suspendCommitPropagation()
+ {
+ OSL_ENSURE( m_bPropagateCommitToRoot, "DocumentStorageAccess::impl_suspendCommitPropagation: already suspended" );
+ m_bPropagateCommitToRoot = false;
+ }
+ void impl_resumeCommitPropagation()
+ {
+ OSL_ENSURE( !m_bPropagateCommitToRoot, "DocumentStorageAccess::impl_resumeCommitPropagation: not suspended" );
+ m_bPropagateCommitToRoot = true;
+ }
+
+};
+
+void DocumentStorageAccess::dispose()
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ for ( NamedStorages::iterator loop = m_aExposedStorages.begin();
+ loop != m_aExposedStorages.end();
+ ++loop
+ )
+ {
+ try
+ {
+ Reference< XTransactionBroadcaster > xBroadcaster( loop->second, UNO_QUERY );
+ if ( xBroadcaster.is() )
+ xBroadcaster->removeTransactionListener( this );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ m_aExposedStorages.clear();
+
+ m_pModelImplementation = NULL;
+}
+
+Reference< XStorage > DocumentStorageAccess::impl_openSubStorage_nothrow( const ::rtl::OUString& _rStorageName, sal_Int32 _nDesiredMode )
+{
+ OSL_ENSURE( _rStorageName.getLength(),"ODatabaseModelImpl::impl_openSubStorage_nothrow: Invalid storage name!" );
+
+ Reference< XStorage > xStorage;
+ try
+ {
+ Reference< XStorage > xRootStorage( m_pModelImplementation->getOrCreateRootStorage() );
+ if ( xRootStorage.is() )
+ {
+ sal_Int32 nRealMode = m_pModelImplementation->m_bDocumentReadOnly ? ElementModes::READ : _nDesiredMode;
+ if ( nRealMode == ElementModes::READ )
+ {
+ Reference< XNameAccess > xSubStorageNames( xRootStorage, UNO_QUERY );
+ if ( xSubStorageNames.is() && !xSubStorageNames->hasByName( _rStorageName ) )
+ return xStorage;
+ }
+
+ xStorage = xRootStorage->openStorageElement( _rStorageName, nRealMode );
+
+ Reference< XTransactionBroadcaster > xBroad( xStorage, UNO_QUERY );
+ if ( xBroad.is() )
+ xBroad->addTransactionListener( this );
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ return xStorage;
+}
+
+void DocumentStorageAccess::disposeStorages()
+{
+ m_bDisposingSubStorages = true;
+
+ NamedStorages::iterator aEnd = m_aExposedStorages.end();
+ for ( NamedStorages::iterator aIter = m_aExposedStorages.begin();
+ aIter != aEnd ;
+ ++aIter
+ )
+ {
+ try
+ {
+ ::comphelper::disposeComponent( aIter->second );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+ m_aExposedStorages.clear();
+
+ m_bDisposingSubStorages = false;
+}
+
+void DocumentStorageAccess::commitStorages() SAL_THROW(( IOException, RuntimeException ))
+{
+ try
+ {
+ for ( NamedStorages::const_iterator aIter = m_aExposedStorages.begin();
+ aIter != m_aExposedStorages.end();
+ ++aIter
+ )
+ {
+ tools::stor::commitStorageIfWriteable( aIter->second );
+ }
+ }
+ catch(const WrappedTargetException&)
+ {
+ // WrappedTargetException not allowed to leave
+ throw IOException();
+ }
+}
+
+bool DocumentStorageAccess::commitEmbeddedStorage( bool _bPreventRootCommits )
+{
+ if ( _bPreventRootCommits )
+ impl_suspendCommitPropagation();
+
+ bool bSuccess = false;
+ try
+ {
+ NamedStorages::const_iterator pos = m_aExposedStorages.find( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "database" ) ) );
+ if ( pos != m_aExposedStorages.end() )
+ bSuccess = tools::stor::commitStorageIfWriteable( pos->second );
+ }
+ catch( Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ if ( _bPreventRootCommits )
+ impl_resumeCommitPropagation();
+
+ return bSuccess;
+
+}
+
+Reference< XStorage > SAL_CALL DocumentStorageAccess::getDocumentSubStorage( const ::rtl::OUString& aStorageName, ::sal_Int32 _nDesiredMode ) throw (RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ NamedStorages::iterator pos = m_aExposedStorages.find( aStorageName );
+ if ( pos == m_aExposedStorages.end() )
+ {
+ Reference< XStorage > xResult = impl_openSubStorage_nothrow( aStorageName, _nDesiredMode );
+ pos = m_aExposedStorages.insert( NamedStorages::value_type( aStorageName, xResult ) ).first;
+ }
+
+ return pos->second;
+}
+
+Sequence< ::rtl::OUString > SAL_CALL DocumentStorageAccess::getDocumentSubStoragesNames( ) throw (IOException, RuntimeException)
+{
+ Reference< XStorage > xRootStor( m_pModelImplementation->getRootStorage() );
+ if ( !xRootStor.is() )
+ return Sequence< ::rtl::OUString >();
+
+ ::std::vector< ::rtl::OUString > aNames;
+
+ Reference< XNameAccess > xNames( xRootStor, UNO_QUERY_THROW );
+ Sequence< ::rtl::OUString > aElementNames( xNames->getElementNames() );
+ for ( sal_Int32 i=0; i<aElementNames.getLength(); ++i )
+ {
+ if ( xRootStor->isStorageElement( aElementNames[i] ) )
+ aNames.push_back( aElementNames[i] );
+ }
+ return aNames.empty()
+ ? Sequence< ::rtl::OUString >()
+ : Sequence< ::rtl::OUString >( &aNames[0], aNames.size() );
+}
+
+void SAL_CALL DocumentStorageAccess::preCommit( const css::lang::EventObject& /*aEvent*/ ) throw (Exception, RuntimeException)
+{
+ // not interested in
+}
+
+void SAL_CALL DocumentStorageAccess::commited( const css::lang::EventObject& aEvent ) throw (RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( m_pModelImplementation )
+ m_pModelImplementation->setModified( sal_True );
+
+ if ( m_pModelImplementation && m_bPropagateCommitToRoot )
+ {
+ Reference< XStorage > xStorage( aEvent.Source, UNO_QUERY );
+
+ // check if this is the dedicated "database" sub storage
+ NamedStorages::const_iterator pos = m_aExposedStorages.find( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "database" ) ) );
+ if ( ( pos != m_aExposedStorages.end() )
+ && ( pos->second == xStorage )
+ )
+ {
+ // if so, also commit the root storage
+ m_pModelImplementation->commitRootStorage();
+ }
+ }
+}
+
+void SAL_CALL DocumentStorageAccess::preRevert( const css::lang::EventObject& /*aEvent*/ ) throw (Exception, RuntimeException)
+{
+ // not interested in
+}
+
+void SAL_CALL DocumentStorageAccess::reverted( const css::lang::EventObject& /*aEvent*/ ) throw (RuntimeException)
+{
+ // not interested in
+}
+
+void SAL_CALL DocumentStorageAccess::disposing( const css::lang::EventObject& Source ) throw ( RuntimeException )
+{
+ OSL_ENSURE( Reference< XStorage >( Source.Source, UNO_QUERY ).is(), "DocumentStorageAccess::disposing: No storage? What's this?" );
+
+ if ( m_bDisposingSubStorages )
+ return;
+
+ for ( NamedStorages::iterator find = m_aExposedStorages.begin();
+ find != m_aExposedStorages.end();
+ ++find
+ )
+ if ( find->second == Source.Source )
+ {
+ m_aExposedStorages.erase( find );
+ break;
+ }
+}
+
+//============================================================
+//= ODatabaseModelImpl
+//============================================================
+DBG_NAME(ODatabaseModelImpl)
+
+ODatabaseModelImpl::ODatabaseModelImpl( const Reference< XMultiServiceFactory >& _rxFactory, ODatabaseContext& _rDBContext )
+ :m_xModel()
+ ,m_xDataSource()
+ ,m_pStorageAccess( NULL )
+ ,m_aMutex()
+ ,m_aMutexFacade( m_aMutex )
+ ,m_aContainer(4)
+ ,m_aMacroMode( *this )
+ ,m_nImposedMacroExecMode( MacroExecMode::NEVER_EXECUTE )
+ ,m_pDBContext( &_rDBContext )
+ ,m_refCount(0)
+ ,m_aEmbeddedMacros()
+ ,m_bModificationLock( false )
+ ,m_bDocumentInitialized( false )
+ ,m_aContext( _rxFactory )
+ ,m_nLoginTimeout(0)
+ ,m_bReadOnly(sal_False)
+ ,m_bPasswordRequired(sal_False)
+ ,m_bSuppressVersionColumns(sal_True)
+ ,m_bModified(sal_False)
+ ,m_bDocumentReadOnly(sal_False)
+ ,m_pSharedConnectionManager(NULL)
+ ,m_nControllerLockCount(0)
+{
+ // some kind of default
+ DBG_CTOR(ODatabaseModelImpl,NULL);
+ m_sConnectURL = ::rtl::OUString::createFromAscii("jdbc:");
+ m_aTableFilter.realloc(1);
+ m_aTableFilter[0] = ::rtl::OUString::createFromAscii("%");
+ impl_construct_nothrow();
+}
+
+ODatabaseModelImpl::ODatabaseModelImpl(
+ const ::rtl::OUString& _rRegistrationName,
+ const Reference< XMultiServiceFactory >& _rxFactory,
+ ODatabaseContext& _rDBContext
+ )
+ :m_xModel()
+ ,m_xDataSource()
+ ,m_pStorageAccess( NULL )
+ ,m_aMutex()
+ ,m_aMutexFacade( m_aMutex )
+ ,m_aContainer(4)
+ ,m_aMacroMode( *this )
+ ,m_nImposedMacroExecMode( MacroExecMode::NEVER_EXECUTE )
+ ,m_pDBContext( &_rDBContext )
+ ,m_refCount(0)
+ ,m_aEmbeddedMacros()
+ ,m_bModificationLock( false )
+ ,m_bDocumentInitialized( false )
+ ,m_aContext( _rxFactory )
+ ,m_sName(_rRegistrationName)
+ ,m_nLoginTimeout(0)
+ ,m_bReadOnly(sal_False)
+ ,m_bPasswordRequired(sal_False)
+ ,m_bSuppressVersionColumns(sal_True)
+ ,m_bModified(sal_False)
+ ,m_bDocumentReadOnly(sal_False)
+ ,m_pSharedConnectionManager(NULL)
+ ,m_nControllerLockCount(0)
+{
+ DBG_CTOR(ODatabaseModelImpl,NULL);
+ impl_construct_nothrow();
+}
+
+ODatabaseModelImpl::~ODatabaseModelImpl()
+{
+ DBG_DTOR(ODatabaseModelImpl,NULL);
+}
+
+void ODatabaseModelImpl::impl_construct_nothrow()
+{
+ // create the property bag to hold the settings (also known as "Info" property)
+ try
+ {
+ // the set of property value types in the bag is limited:
+ Sequence< Type > aAllowedTypes(6);
+ Type* pAllowedType = aAllowedTypes.getArray();
+ *pAllowedType++ = ::getCppuType( static_cast< sal_Bool* >( NULL ) );
+ *pAllowedType++ = ::getCppuType( static_cast< double* >( NULL ) );
+ *pAllowedType++ = ::getCppuType( static_cast< ::rtl::OUString* >( NULL ) );
+ *pAllowedType++ = ::getCppuType( static_cast< sal_Int32* >( NULL ) );
+ *pAllowedType++ = ::getCppuType( static_cast< sal_Int16* >( NULL ) );
+ *pAllowedType++ = ::getCppuType( static_cast< Sequence< Any >* >( NULL ) );
+
+ Sequence< Any > aInitArgs( 2 );
+ aInitArgs[0] <<= NamedValue(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AutomaticAddition" ) ),
+ makeAny( (sal_Bool)sal_True )
+ );
+ aInitArgs[1] <<= NamedValue(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AllowedTypes" ) ),
+ makeAny( aAllowedTypes )
+ );
+
+ m_xSettings.set( m_aContext.createComponentWithArguments( "com.sun.star.beans.PropertyBag", aInitArgs ), UNO_QUERY_THROW );
+
+ // insert the default settings
+ Reference< XPropertyContainer > xContainer( m_xSettings, UNO_QUERY_THROW );
+ Reference< XSet > xSettingsSet( m_xSettings, UNO_QUERY_THROW );
+ const AsciiPropertyValue* pSettings = getDefaultDataSourceSettings();
+ for ( ; pSettings->AsciiName; ++pSettings )
+ {
+ if ( !pSettings->DefaultValue.hasValue() )
+ {
+ Property aProperty(
+ ::rtl::OUString::createFromAscii( pSettings->AsciiName ),
+ -1,
+ pSettings->ValueType,
+ PropertyAttribute::BOUND | PropertyAttribute::MAYBEDEFAULT | PropertyAttribute::MAYBEVOID
+ );
+ xSettingsSet->insert( makeAny( aProperty ) );
+ }
+ else
+ {
+ xContainer->addProperty(
+ ::rtl::OUString::createFromAscii( pSettings->AsciiName ),
+ PropertyAttribute::BOUND | PropertyAttribute::MAYBEDEFAULT,
+ pSettings->DefaultValue
+ );
+ }
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ m_pDBContext->appendAtTerminateListener(*this);
+}
+
+namespace
+{
+ ::rtl::OUString lcl_getContainerStorageName_throw( ODatabaseModelImpl::ObjectType _eType )
+ {
+ const sal_Char* pAsciiName( NULL );
+ switch ( _eType )
+ {
+ case ODatabaseModelImpl::E_FORM: pAsciiName = "forms"; break;
+ case ODatabaseModelImpl::E_REPORT: pAsciiName = "reports"; break;
+ case ODatabaseModelImpl::E_QUERY: pAsciiName = "queries"; break;
+ case ODatabaseModelImpl::E_TABLE: pAsciiName = "tables"; break;
+ default:
+ throw RuntimeException();
+ }
+ return ::rtl::OUString::createFromAscii( pAsciiName );
+ }
+
+ bool lcl_hasObjectWithMacros_throw( const ODefinitionContainer_Impl& _rObjectDefinitions, const Reference< XStorage >& _rxContainerStorage )
+ {
+ bool bSomeDocHasMacros = false;
+
+ for ( ODefinitionContainer_Impl::const_iterator object = _rObjectDefinitions.begin();
+ ( object != _rObjectDefinitions.end() ) && !bSomeDocHasMacros;
+ ++object
+ )
+ {
+#if OSL_DEBUG_LEVEL > 0
+ const ::rtl::OUString& rName( object->first ); (void)rName;
+#endif
+
+ const TContentPtr& rDefinition( object->second );
+ const ::rtl::OUString& rPersistentName( rDefinition->m_aProps.sPersistentName );
+
+ if ( !rPersistentName.getLength() )
+ { // it's a logical sub folder used to organize the real objects
+ const ODefinitionContainer_Impl& rSubFoldersObjectDefinitions( dynamic_cast< const ODefinitionContainer_Impl& >( *rDefinition.get() ) );
+ bSomeDocHasMacros = lcl_hasObjectWithMacros_throw( rSubFoldersObjectDefinitions, _rxContainerStorage );
+ continue;
+ }
+
+ bSomeDocHasMacros = ODatabaseModelImpl::objectHasMacros( _rxContainerStorage, rPersistentName );
+ }
+ return bSomeDocHasMacros;
+ }
+
+ bool lcl_hasObjectsWithMacros_nothrow( ODatabaseModelImpl& _rModel, const ODatabaseModelImpl::ObjectType _eType )
+ {
+ bool bSomeDocHasMacros = false;
+
+ const OContentHelper_Impl& rContainerData( *_rModel.getObjectContainer( _eType ).get() );
+ const ODefinitionContainer_Impl& rObjectDefinitions = dynamic_cast< const ODefinitionContainer_Impl& >( rContainerData );
+
+ try
+ {
+ Reference< XStorage > xContainerStorage( _rModel.getStorage( _eType, ElementModes::READWRITE ) );
+ // note the READWRITE here: If the storage already existed before, then the OpenMode will
+ // be ignored, anyway.
+ // If the storage did not yet exist, then it will be created. If the database document
+ // is read-only, the OpenMode will be automatically downgraded to READ. Otherwise,
+ // the storage will in fact be created as READWRITE. While this is not strictly necessary
+ // for this particular use case here, it is required since the storage is *cached*, and
+ // later use cases will need the READWRITE mode.
+
+ if ( xContainerStorage.is() )
+ bSomeDocHasMacros = lcl_hasObjectWithMacros_throw( rObjectDefinitions, xContainerStorage );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ // be on the safe side: If we can't reliably determine whether there are macros,
+ // assume there actually are. Better this way, than the other way round.
+ bSomeDocHasMacros = true;
+ }
+
+ return bSomeDocHasMacros;
+ }
+}
+
+bool ODatabaseModelImpl::objectHasMacros( const Reference< XStorage >& _rxContainerStorage, const ::rtl::OUString& _rPersistentName )
+{
+ OSL_PRECOND( _rxContainerStorage.is(), "ODatabaseModelImpl::objectHasMacros: this will crash!" );
+
+ bool bHasMacros = true;
+ try
+ {
+ if ( !_rxContainerStorage->hasByName( _rPersistentName ) )
+ return false;
+
+ Reference< XStorage > xObjectStor( _rxContainerStorage->openStorageElement(
+ _rPersistentName, ElementModes::READ ) );
+
+ bHasMacros = ::sfx2::DocumentMacroMode::storageHasMacros( xObjectStor );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return bHasMacros;
+}
+
+void ODatabaseModelImpl::reset()
+{
+ m_bReadOnly = sal_False;
+ ::std::vector< TContentPtr > aEmptyContainers( 4 );
+ m_aContainer.swap( aEmptyContainers );
+
+ if ( m_pStorageAccess )
+ {
+ m_pStorageAccess->dispose();
+ m_pStorageAccess->release();
+ m_pStorageAccess = NULL;
+ }
+}
+
+void SAL_CALL ODatabaseModelImpl::disposing( const ::com::sun::star::lang::EventObject& Source ) throw(RuntimeException)
+{
+ Reference<XConnection> xCon(Source.Source,UNO_QUERY);
+ if ( xCon.is() )
+ {
+ bool bStore = false;
+ OWeakConnectionArray::iterator aEnd = m_aConnections.end();
+ for (OWeakConnectionArray::iterator i = m_aConnections.begin(); aEnd != i; ++i)
+ {
+ if ( xCon == i->get() )
+ {
+ *i = OWeakConnection();
+ bStore = true;
+ break;
+ }
+ }
+
+ if ( bStore )
+ commitRootStorage();
+ }
+ else
+ {
+ OSL_ENSURE( false, "ODatabaseModelImpl::disposing: where does this come from?" );
+ }
+}
+
+void ODatabaseModelImpl::clearConnections()
+{
+ OWeakConnectionArray aConnections;
+ aConnections.swap( m_aConnections );
+
+ Reference< XConnection > xConn;
+ OWeakConnectionArray::iterator aEnd = aConnections.end();
+ for ( OWeakConnectionArray::iterator i = aConnections.begin(); aEnd != i; ++i )
+ {
+ xConn = *i;
+ if ( xConn.is() )
+ {
+ try
+ {
+ xConn->close();
+ }
+ catch(const Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+ }
+
+ m_pSharedConnectionManager = NULL;
+ m_xSharedConnectionManager = NULL;
+}
+
+void ODatabaseModelImpl::dispose()
+{
+ // dispose the data source and the model
+ try
+ {
+ Reference< XDataSource > xDS( m_xDataSource );
+ ::comphelper::disposeComponent( xDS );
+
+ Reference< XModel > xModel( m_xModel );
+ ::comphelper::disposeComponent( xModel );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ m_xDataSource = WeakReference<XDataSource>();
+ m_xModel = WeakReference< XModel >();
+
+ ::std::vector<TContentPtr>::iterator aIter = m_aContainer.begin();
+ ::std::vector<TContentPtr>::iterator aEnd = m_aContainer.end();
+ for (;aIter != aEnd ; ++aIter)
+ {
+ if ( aIter->get() )
+ (*aIter)->m_pDataSource = NULL;
+ }
+ m_aContainer.clear();
+
+ clearConnections();
+
+ m_xNumberFormatsSupplier = NULL;
+
+ try
+ {
+ sal_Bool bCouldStore = commitEmbeddedStorage( true );
+ // "true" means that committing the embedded storage should not trigger committing the root
+ // storage. This is because we are going to commit the root storage ourself, anyway
+ disposeStorages();
+ if ( bCouldStore )
+ commitRootStorage();
+
+ impl_switchToStorage_throw( NULL );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ if ( m_pStorageAccess )
+ {
+ m_pStorageAccess->dispose();
+ m_pStorageAccess->release();
+ m_pStorageAccess = NULL;
+ }
+}
+
+const Reference< XNumberFormatsSupplier > & ODatabaseModelImpl::getNumberFormatsSupplier()
+{
+ if (!m_xNumberFormatsSupplier.is())
+ {
+ // the arguments : the locale of the current user
+ UserInformation aUserInfo;
+ Sequence< Any > aArguments(1);
+ aArguments.getArray()[0] <<= aUserInfo.getUserLanguage();
+
+ m_xNumberFormatsSupplier.set(
+ m_aContext.createComponentWithArguments( "com.sun.star.util.NumberFormatsSupplier", aArguments ), UNO_QUERY_THROW );
+ DBG_ASSERT(m_xNumberFormatsSupplier.is(), "ODatabaseModelImpl::getNumberFormatsSupplier : could not instantiate the formats supplier !");
+ }
+ return m_xNumberFormatsSupplier;
+}
+
+void ODatabaseModelImpl::setDocFileLocation( const ::rtl::OUString& i_rLoadedFrom )
+{
+ ENSURE_OR_THROW( i_rLoadedFrom.getLength(), "invalid URL" );
+ m_sDocFileLocation = i_rLoadedFrom;
+}
+
+void ODatabaseModelImpl::setResource( const ::rtl::OUString& i_rDocumentURL, const Sequence< PropertyValue >& _rArgs )
+{
+ ENSURE_OR_THROW( i_rDocumentURL.getLength(), "invalid URL" );
+
+ ::comphelper::NamedValueCollection aMediaDescriptor( _rArgs );
+#if OSL_DEBUG_LEVEL > 0
+ if ( aMediaDescriptor.has( "SalvagedFile" ) )
+ {
+ ::rtl::OUString sSalvagedFile( aMediaDescriptor.getOrDefault( "SalvagedFile", ::rtl::OUString() ) );
+ // If SalvagedFile is an empty string, this indicates "the document is being recovered, but i_rDocumentURL already
+ // is the real document URL, not the temporary document location"
+ if ( !sSalvagedFile.getLength() )
+ sSalvagedFile = i_rDocumentURL;
+
+ OSL_ENSURE( sSalvagedFile == i_rDocumentURL, "ODatabaseModelImpl::setResource: inconsistency!" );
+ // nowadays, setResource should only be called with the logical URL of the document
+ }
+#endif
+
+ m_aMediaDescriptor = stripLoadArguments( aMediaDescriptor );
+
+ impl_switchToLogicalURL( i_rDocumentURL );
+}
+
+::comphelper::NamedValueCollection ODatabaseModelImpl::stripLoadArguments( const ::comphelper::NamedValueCollection& _rArguments )
+{
+ OSL_ENSURE( !_rArguments.has( "Model" ), "ODatabaseModelImpl::stripLoadArguments: this is suspicious (1)!" );
+ OSL_ENSURE( !_rArguments.has( "ViewName" ), "ODatabaseModelImpl::stripLoadArguments: this is suspicious (2)!" );
+
+ ::comphelper::NamedValueCollection aMutableArgs( _rArguments );
+ aMutableArgs.remove( "Model" );
+ aMutableArgs.remove( "ViewName" );
+ return aMutableArgs;
+}
+
+void ODatabaseModelImpl::disposeStorages() SAL_THROW(())
+{
+ getDocumentStorageAccess()->disposeStorages();
+}
+
+Reference< XSingleServiceFactory > ODatabaseModelImpl::createStorageFactory() const
+{
+ return Reference< XSingleServiceFactory >( m_aContext.createComponent( "com.sun.star.embed.StorageFactory" ), UNO_QUERY_THROW );
+}
+
+void ODatabaseModelImpl::commitRootStorage()
+{
+ Reference< XStorage > xStorage( getOrCreateRootStorage() );
+#if OSL_DEBUG_LEVEL > 0
+ bool bSuccess =
+#endif
+ commitStorageIfWriteable_ignoreErrors( xStorage );
+ OSL_ENSURE( bSuccess || !xStorage.is(),
+ "ODatabaseModelImpl::commitRootStorage: could commit the storage!" );
+}
+
+Reference< XStorage > ODatabaseModelImpl::getOrCreateRootStorage()
+{
+ if ( !m_xDocumentStorage.is() )
+ {
+ Reference< XSingleServiceFactory> xStorageFactory = createStorageFactory();
+ if ( xStorageFactory.is() )
+ {
+ Any aSource;
+ aSource = m_aMediaDescriptor.get( "Stream" );
+ if ( !aSource.hasValue() )
+ aSource = m_aMediaDescriptor.get( "InputStream" );
+ if ( !aSource.hasValue() && m_sDocFileLocation.getLength() )
+ aSource <<= m_sDocFileLocation;
+ // TODO: shouldn't we also check URL?
+
+ OSL_ENSURE( aSource.hasValue(), "ODatabaseModelImpl::getOrCreateRootStorage: no source to create the storage from!" );
+
+ if ( aSource.hasValue() )
+ {
+ Sequence< Any > aStorageCreationArgs(2);
+ aStorageCreationArgs[0] = aSource;
+ aStorageCreationArgs[1] <<= ElementModes::READWRITE;
+
+ Reference< XStorage > xDocumentStorage;
+ try
+ {
+ xDocumentStorage.set( xStorageFactory->createInstanceWithArguments( aStorageCreationArgs ), UNO_QUERY_THROW );
+ }
+ catch( const Exception& )
+ {
+ m_bDocumentReadOnly = sal_True;
+ aStorageCreationArgs[1] <<= ElementModes::READ;
+ try
+ {
+ xDocumentStorage.set( xStorageFactory->createInstanceWithArguments( aStorageCreationArgs ), UNO_QUERY_THROW );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ impl_switchToStorage_throw( xDocumentStorage );
+ }
+ }
+ }
+ return m_xDocumentStorage.getTyped();
+}
+
+DocumentStorageAccess* ODatabaseModelImpl::getDocumentStorageAccess()
+{
+ if ( !m_pStorageAccess )
+ {
+ m_pStorageAccess = new DocumentStorageAccess( *this );
+ m_pStorageAccess->acquire();
+ }
+ return m_pStorageAccess;
+}
+
+void ODatabaseModelImpl::modelIsDisposing( const bool _wasInitialized, ResetModelAccess )
+{
+ m_xModel = Reference< XModel >();
+
+ // Basic libraries and Dialog libraries are a model facet, though held at this impl class.
+ // They automatically dispose themself when the model they belong to is being disposed.
+ // So, to not be tempted to do anything with them, again, we reset them.
+ m_xBasicLibraries.clear();
+ m_xDialogLibraries.clear();
+
+ m_bDocumentInitialized = _wasInitialized;
+}
+
+Reference< XDocumentSubStorageSupplier > ODatabaseModelImpl::getDocumentSubStorageSupplier()
+{
+ return getDocumentStorageAccess();
+}
+
+bool ODatabaseModelImpl::commitEmbeddedStorage( bool _bPreventRootCommits )
+{
+ return getDocumentStorageAccess()->commitEmbeddedStorage( _bPreventRootCommits );
+}
+
+bool ODatabaseModelImpl::commitStorageIfWriteable_ignoreErrors( const Reference< XStorage >& _rxStorage ) SAL_THROW(())
+{
+ bool bSuccess = false;
+ try
+ {
+ bSuccess = tools::stor::commitStorageIfWriteable( _rxStorage );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return bSuccess;
+}
+
+void ODatabaseModelImpl::setModified( sal_Bool _bModified )
+{
+ if ( isModifyLocked() )
+ return;
+
+ try
+ {
+ Reference< XModifiable > xModi( m_xModel.get(), UNO_QUERY );
+ if ( xModi.is() )
+ xModi->setModified( _bModified );
+ else
+ m_bModified = _bModified;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+}
+
+Reference<XDataSource> ODatabaseModelImpl::getOrCreateDataSource()
+{
+ Reference<XDataSource> xDs = m_xDataSource;
+ if ( !xDs.is() )
+ {
+ xDs = new ODatabaseSource(this);
+ m_xDataSource = xDs;
+ }
+ return xDs;
+}
+
+Reference< XModel> ODatabaseModelImpl::getModel_noCreate() const
+{
+ return m_xModel;
+}
+
+Reference< XModel > ODatabaseModelImpl::createNewModel_deliverOwnership( bool _bInitialize )
+{
+ Reference< XModel > xModel( m_xModel );
+ OSL_PRECOND( !xModel.is(), "ODatabaseModelImpl::createNewModel_deliverOwnership: not to be called if there already is a model!" );
+ if ( !xModel.is() )
+ {
+ bool bHadModelBefore = m_bDocumentInitialized;
+
+ xModel = ODatabaseDocument::createDatabaseDocument( this, ODatabaseDocument::FactoryAccess() );
+ m_xModel = xModel;
+
+ try
+ {
+ Reference< XSet > xModelCollection;
+ if ( m_aContext.createComponent( "com.sun.star.frame.GlobalEventBroadcaster", xModelCollection ) )
+ xModelCollection->insert( makeAny( xModel ) );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ if ( bHadModelBefore )
+ {
+ // do an attachResources
+ // In case the document is loaded regularly, this is not necessary, as our loader will do it.
+ // However, in case that the document is implicitly created by asking the data source for the document,
+ // then nobody would call the doc's attachResource. So, we do it here, to ensure it's in a proper
+ // state, fires all events, and so on.
+ // #i105505# / 2009-10-02 / frank.schoenheit@sun.com
+ xModel->attachResource( xModel->getURL(), m_aMediaDescriptor.getPropertyValues() );
+ }
+
+ if ( _bInitialize )
+ {
+ try
+ {
+ Reference< XLoadable > xLoad( xModel, UNO_QUERY_THROW );
+ xLoad->initNew();
+ }
+ catch( RuntimeException& ) { throw; }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+ }
+ return xModel;
+}
+
+oslInterlockedCount SAL_CALL ODatabaseModelImpl::acquire()
+{
+ return osl_incrementInterlockedCount(&m_refCount);
+}
+
+oslInterlockedCount SAL_CALL ODatabaseModelImpl::release()
+{
+ if ( osl_decrementInterlockedCount(&m_refCount) == 0 )
+ {
+ acquire(); // prevent multiple releases
+ m_pDBContext->removeFromTerminateListener(*this);
+ dispose();
+ m_pDBContext->storeTransientProperties(*this);
+ revokeDataSource();
+ delete this;
+ return 0;
+ }
+ return m_refCount;
+}
+
+void ODatabaseModelImpl::commitStorages() SAL_THROW(( IOException, RuntimeException ))
+{
+ getDocumentStorageAccess()->commitStorages();
+}
+
+Reference< XStorage > ODatabaseModelImpl::getStorage( const ObjectType _eType, const sal_Int32 _nDesiredMode )
+{
+ return getDocumentStorageAccess()->getDocumentSubStorage( getObjectContainerStorageName( _eType ), _nDesiredMode );
+}
+
+const AsciiPropertyValue* ODatabaseModelImpl::getDefaultDataSourceSettings()
+{
+ static const AsciiPropertyValue aKnownSettings[] =
+ {
+ // known JDBC settings
+ AsciiPropertyValue( "JavaDriverClass", makeAny( ::rtl::OUString() ) ),
+ AsciiPropertyValue( "JavaDriverClassPath", makeAny( ::rtl::OUString() ) ),
+ AsciiPropertyValue( "IgnoreCurrency", makeAny( (sal_Bool)sal_False ) ),
+ // known settings for file-based drivers
+ AsciiPropertyValue( "Extension", makeAny( ::rtl::OUString() ) ),
+ AsciiPropertyValue( "CharSet", makeAny( ::rtl::OUString() ) ),
+ AsciiPropertyValue( "HeaderLine", makeAny( (sal_Bool)sal_True ) ),
+ AsciiPropertyValue( "FieldDelimiter", makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "," ) ) ) ),
+ AsciiPropertyValue( "StringDelimiter", makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\"" ) ) ) ),
+ AsciiPropertyValue( "DecimalDelimiter", makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "." ) ) ) ),
+ AsciiPropertyValue( "ThousandDelimiter", makeAny( ::rtl::OUString() ) ),
+ AsciiPropertyValue( "ShowDeleted", makeAny( (sal_Bool)sal_False ) ),
+ // known ODBC settings
+ AsciiPropertyValue( "SystemDriverSettings", makeAny( ::rtl::OUString() ) ),
+ AsciiPropertyValue( "UseCatalog", makeAny( (sal_Bool)sal_False ) ),
+ AsciiPropertyValue( "TypeInfoSettings", makeAny( Sequence< Any >()) ),
+ // settings related to auto increment handling
+ AsciiPropertyValue( "AutoIncrementCreation", makeAny( ::rtl::OUString() ) ),
+ AsciiPropertyValue( "AutoRetrievingStatement", makeAny( ::rtl::OUString() ) ),
+ AsciiPropertyValue( "IsAutoRetrievingEnabled", makeAny( (sal_Bool)sal_False ) ),
+ // known Adabas D driver setting
+ AsciiPropertyValue( "ShutdownDatabase", makeAny( (sal_Bool)sal_False ) ),
+ AsciiPropertyValue( "DataCacheSizeIncrement", makeAny( (sal_Int32)20 ) ),
+ AsciiPropertyValue( "DataCacheSize", makeAny( (sal_Int32)20 ) ),
+ AsciiPropertyValue( "ControlUser", makeAny( ::rtl::OUString() ) ),
+ AsciiPropertyValue( "ControlPassword", makeAny( ::rtl::OUString() ) ),
+ // known LDAP driver settings
+ AsciiPropertyValue( "HostName", makeAny( ::rtl::OUString() ) ),
+ AsciiPropertyValue( "PortNumber", makeAny( (sal_Int32)389 ) ),
+ AsciiPropertyValue( "BaseDN", makeAny( ::rtl::OUString() ) ),
+ AsciiPropertyValue( "MaxRowCount", makeAny( (sal_Int32)100 ) ),
+ // known MySQLNative driver settings
+ AsciiPropertyValue( "LocalSocket", makeAny( ::rtl::OUString() ) ),
+ AsciiPropertyValue( "NamedPipe", makeAny( ::rtl::OUString() ) ),
+ // misc known driver settings
+ AsciiPropertyValue( "ParameterNameSubstitution", makeAny( (sal_Bool)sal_False ) ),
+ AsciiPropertyValue( "AddIndexAppendix", makeAny( (sal_Bool)sal_True ) ),
+ AsciiPropertyValue( "IgnoreDriverPrivileges", makeAny( (sal_Bool)sal_True ) ),
+ AsciiPropertyValue( "ImplicitCatalogRestriction", ::cppu::UnoType< ::rtl::OUString >::get() ),
+ AsciiPropertyValue( "ImplicitSchemaRestriction", ::cppu::UnoType< ::rtl::OUString >::get() ),
+ AsciiPropertyValue( "PrimaryKeySupport", ::cppu::UnoType< sal_Bool >::get() ),
+ AsciiPropertyValue( "ShowColumnDescription", makeAny( (sal_Bool)sal_False ) ),
+ // known SDB level settings
+ AsciiPropertyValue( "NoNameLengthLimit", makeAny( (sal_Bool)sal_False ) ),
+ AsciiPropertyValue( "AppendTableAliasName", makeAny( (sal_Bool)sal_False ) ),
+ AsciiPropertyValue( "GenerateASBeforeCorrelationName", makeAny( (sal_Bool)sal_True ) ),
+ AsciiPropertyValue( "ColumnAliasInOrderBy", makeAny( (sal_Bool)sal_True ) ),
+ AsciiPropertyValue( "EnableSQL92Check", makeAny( (sal_Bool)sal_False ) ),
+ AsciiPropertyValue( "BooleanComparisonMode", makeAny( BooleanComparisonMode::EQUAL_INTEGER ) ),
+ AsciiPropertyValue( "TableTypeFilterMode", makeAny( (sal_Int32)3 ) ),
+ AsciiPropertyValue( "RespectDriverResultSetType", makeAny( (sal_Bool)sal_False ) ),
+ AsciiPropertyValue( "UseSchemaInSelect", makeAny( (sal_Bool)sal_True ) ),
+ AsciiPropertyValue( "UseCatalogInSelect", makeAny( (sal_Bool)sal_True ) ),
+ AsciiPropertyValue( "EnableOuterJoinEscape", makeAny( (sal_Bool)sal_True ) ),
+ AsciiPropertyValue( "PreferDosLikeLineEnds", makeAny( (sal_Bool)sal_False ) ),
+ AsciiPropertyValue( "FormsCheckRequiredFields", makeAny( (sal_Bool)sal_True ) ),
+ AsciiPropertyValue( "EscapeDateTime", makeAny( (sal_Bool)sal_True ) ),
+
+ // known services to handle database tasks
+ AsciiPropertyValue( "TableAlterationServiceName", makeAny( ::rtl::OUString() ) ),
+ AsciiPropertyValue( "TableRenameServiceName", makeAny( ::rtl::OUString() ) ),
+ AsciiPropertyValue( "ViewAlterationServiceName", makeAny( ::rtl::OUString() ) ),
+ AsciiPropertyValue( "ViewAccessServiceName", makeAny( ::rtl::OUString() ) ),
+ AsciiPropertyValue( "CommandDefinitions", makeAny( ::rtl::OUString() ) ),
+ AsciiPropertyValue( "Forms", makeAny( ::rtl::OUString() ) ),
+ AsciiPropertyValue( "Reports", makeAny( ::rtl::OUString() ) ),
+ AsciiPropertyValue( "KeyAlterationServiceName", makeAny( ::rtl::OUString() ) ),
+ AsciiPropertyValue( "IndexAlterationServiceName", makeAny( ::rtl::OUString() ) ),
+
+ AsciiPropertyValue()
+ };
+ return aKnownSettings;
+}
+
+TContentPtr& ODatabaseModelImpl::getObjectContainer( ObjectType _eType )
+{
+ OSL_PRECOND( _eType >= E_FORM && _eType <= E_TABLE, "ODatabaseModelImpl::getObjectContainer: illegal index!" );
+ TContentPtr& rContentPtr = m_aContainer[ _eType ];
+
+ if ( !rContentPtr.get() )
+ {
+ rContentPtr = TContentPtr( new ODefinitionContainer_Impl );
+ rContentPtr->m_pDataSource = this;
+ rContentPtr->m_aProps.aTitle = lcl_getContainerStorageName_throw( _eType );
+ }
+ return rContentPtr;
+}
+
+void ODatabaseModelImpl::revokeDataSource() const
+{
+ if ( m_pDBContext && m_sDocumentURL.getLength() )
+ m_pDBContext->revokeDatabaseDocument( *this );
+}
+
+bool ODatabaseModelImpl::adjustMacroMode_AutoReject()
+{
+ return m_aMacroMode.adjustMacroMode( NULL );
+}
+
+bool ODatabaseModelImpl::checkMacrosOnLoading()
+{
+ Reference< XInteractionHandler > xInteraction;
+ xInteraction = m_aMediaDescriptor.getOrDefault( "InteractionHandler", xInteraction );
+ return m_aMacroMode.checkMacrosOnLoading( xInteraction );
+}
+
+void ODatabaseModelImpl::resetMacroExecutionMode()
+{
+ m_aMacroMode = ::sfx2::DocumentMacroMode( *this );
+}
+
+Reference< XStorageBasedLibraryContainer > ODatabaseModelImpl::getLibraryContainer( bool _bScript )
+{
+ Reference< XStorageBasedLibraryContainer >& rxContainer( _bScript ? m_xBasicLibraries : m_xDialogLibraries );
+ if ( rxContainer.is() )
+ return rxContainer;
+
+ Reference< XStorageBasedDocument > xDocument( getModel_noCreate(), UNO_QUERY_THROW );
+ // this is only to be called if there already exists a document model - in fact, it is
+ // to be called by the document model only
+
+ try
+ {
+ Reference< XStorageBasedLibraryContainer > (*Factory)( const Reference< XComponentContext >&, const Reference< XStorageBasedDocument >&)
+ = _bScript ? &DocumentScriptLibraryContainer::create : &DocumentDialogLibraryContainer::create;
+
+ rxContainer.set(
+ (*Factory)( m_aContext.getUNOContext(), xDocument ),
+ UNO_QUERY_THROW
+ );
+ }
+ catch( const RuntimeException& )
+ {
+ throw;
+ }
+ catch( const Exception& )
+ {
+ throw WrappedTargetRuntimeException(
+ ::rtl::OUString(),
+ xDocument,
+ ::cppu::getCaughtException()
+ );
+ }
+ return rxContainer;
+}
+
+void ODatabaseModelImpl::storeLibraryContainersTo( const Reference< XStorage >& _rxToRootStorage )
+{
+ if ( m_xBasicLibraries.is() )
+ m_xBasicLibraries->storeLibrariesToStorage( _rxToRootStorage );
+
+ if ( m_xDialogLibraries.is() )
+ m_xDialogLibraries->storeLibrariesToStorage( _rxToRootStorage );
+}
+
+Reference< XStorage > ODatabaseModelImpl::switchToStorage( const Reference< XStorage >& _rxNewRootStorage )
+{
+ if ( !_rxNewRootStorage.is() )
+ throw IllegalArgumentException();
+
+ return impl_switchToStorage_throw( _rxNewRootStorage );
+}
+
+namespace
+{
+ void lcl_modifyListening( ::sfx2::IModifiableDocument& _rDocument,
+ const Reference< XStorage >& _rxStorage, ::rtl::Reference< ::sfx2::DocumentStorageModifyListener >& _inout_rListener,
+ ::osl::SolarMutex& _rMutex, bool _bListen )
+ {
+ Reference< XModifiable > xModify( _rxStorage, UNO_QUERY );
+ OSL_ENSURE( xModify.is() || !_rxStorage.is(), "lcl_modifyListening: storage can't notify us!" );
+
+ if ( xModify.is() && !_bListen && _inout_rListener.is() )
+ {
+ xModify->removeModifyListener( _inout_rListener.get() );
+ }
+
+ if ( _inout_rListener.is() )
+ {
+ _inout_rListener->dispose();
+ _inout_rListener = NULL;
+ }
+
+ if ( xModify.is() && _bListen )
+ {
+ _inout_rListener = new ::sfx2::DocumentStorageModifyListener( _rDocument, _rMutex );
+ xModify->addModifyListener( _inout_rListener.get() );
+ }
+ }
+}
+
+namespace
+{
+ static void lcl_rebaseScriptStorage_throw( const Reference< XStorageBasedLibraryContainer >& _rxContainer,
+ const Reference< XStorage >& _rxNewRootStorage )
+ {
+ if ( _rxContainer.is() )
+ {
+ if ( _rxNewRootStorage.is() )
+ _rxContainer->setRootStorage( _rxNewRootStorage );
+// else
+ // TODO: what to do here? dispose the container?
+ }
+ }
+}
+
+Reference< XStorage > ODatabaseModelImpl::impl_switchToStorage_throw( const Reference< XStorage >& _rxNewRootStorage )
+{
+ // stop listening for modifications at the old storage
+ lcl_modifyListening( *this, m_xDocumentStorage.getTyped(), m_pStorageModifyListener, m_aMutexFacade, false );
+
+ // set new storage
+ m_xDocumentStorage.reset( _rxNewRootStorage, SharedStorage::TakeOwnership );
+
+ // start listening for modifications
+ lcl_modifyListening( *this, m_xDocumentStorage.getTyped(), m_pStorageModifyListener, m_aMutexFacade, true );
+
+ // forward new storage to Basic and Dialog library containers
+ lcl_rebaseScriptStorage_throw( m_xBasicLibraries, m_xDocumentStorage.getTyped() );
+ lcl_rebaseScriptStorage_throw( m_xDialogLibraries, m_xDocumentStorage.getTyped() );
+
+ m_bReadOnly = !tools::stor::storageIsWritable_nothrow( m_xDocumentStorage.getTyped() );
+ // TODO: our data source, if it exists, must broadcast the change of its ReadOnly property
+
+ return m_xDocumentStorage.getTyped();
+}
+
+void ODatabaseModelImpl::impl_switchToLogicalURL( const ::rtl::OUString& i_rDocumentURL )
+{
+ if ( i_rDocumentURL == m_sDocumentURL )
+ return;
+
+ const ::rtl::OUString sOldURL( m_sDocumentURL );
+ // update our name, if necessary
+ if ( ( m_sName == m_sDocumentURL ) // our name is our old URL
+ || ( !m_sName.getLength() ) // we do not have a name, yet (i.e. are not registered at the database context)
+ )
+ {
+ INetURLObject aURL( i_rDocumentURL );
+ if ( aURL.GetProtocol() != INET_PROT_NOT_VALID )
+ {
+ m_sName = i_rDocumentURL;
+ // TODO: our data source must broadcast the change of the Name property
+ }
+ }
+
+ // remember URL
+ m_sDocumentURL = i_rDocumentURL;
+
+ // update our location, if necessary
+ if ( m_sDocFileLocation.getLength() == 0 )
+ m_sDocFileLocation = m_sDocumentURL;
+
+ // register at the database context, or change registration
+ if ( m_pDBContext )
+ {
+ if ( sOldURL.getLength() )
+ m_pDBContext->databaseDocumentURLChange( sOldURL, m_sDocumentURL );
+ else
+ m_pDBContext->registerDatabaseDocument( *this );
+ }
+}
+
+::rtl::OUString ODatabaseModelImpl::getObjectContainerStorageName( const ObjectType _eType )
+{
+ return lcl_getContainerStorageName_throw( _eType );
+}
+
+sal_Int16 ODatabaseModelImpl::getCurrentMacroExecMode() const
+{
+ sal_Int16 nCurrentMode = MacroExecMode::NEVER_EXECUTE;
+ try
+ {
+ nCurrentMode = m_aMediaDescriptor.getOrDefault( "MacroExecutionMode", nCurrentMode );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return nCurrentMode;
+}
+
+sal_Bool ODatabaseModelImpl::setCurrentMacroExecMode( sal_uInt16 nMacroMode )
+{
+ m_aMediaDescriptor.put( "MacroExecutionMode", nMacroMode );
+ return sal_True;
+}
+
+::rtl::OUString ODatabaseModelImpl::getDocumentLocation() const
+{
+ return getURL();
+ // formerly, we returned getDocFileLocation here, which is the location of the file from which we
+ // recovered the "real" document.
+ // However, during CWS autorecovery evolving, we clarified (with MAV/MT) the role of XModel::getURL and
+ // XStorable::getLocation. In this course, we agreed that for a macro security check, the *document URL*
+ // (not the recovery file URL) is to be used: The recovery file lies in the backup folder, and by definition,
+ // this folder is considered to be secure. So, the document URL needs to be used to decide about the security.
+}
+
+Reference< XStorage > ODatabaseModelImpl::getZipStorageToSign()
+{
+ // we do not support signing the scripting storages, so we're allowed to
+ // return <NULL/> here.
+ return Reference< XStorage >();
+}
+
+ODatabaseModelImpl::EmbeddedMacros ODatabaseModelImpl::determineEmbeddedMacros()
+{
+ if ( !m_aEmbeddedMacros )
+ {
+ if ( ::sfx2::DocumentMacroMode::storageHasMacros( const_cast< ODatabaseModelImpl* >( this )->getOrCreateRootStorage() ) )
+ {
+ m_aEmbeddedMacros.reset( eDocumentWideMacros );
+ }
+ else if ( lcl_hasObjectsWithMacros_nothrow( const_cast< ODatabaseModelImpl& >( *this ), E_FORM )
+ || lcl_hasObjectsWithMacros_nothrow( const_cast< ODatabaseModelImpl& >( *this ), E_REPORT )
+ )
+ {
+ m_aEmbeddedMacros.reset( eSubDocumentMacros );
+ }
+ else
+ {
+ m_aEmbeddedMacros.reset( eNoMacros );
+ }
+ }
+ return *m_aEmbeddedMacros;
+}
+
+sal_Bool ODatabaseModelImpl::documentStorageHasMacros() const
+{
+ const_cast< ODatabaseModelImpl* >( this )->determineEmbeddedMacros();
+ return ( *m_aEmbeddedMacros != eNoMacros );
+}
+
+Reference< XEmbeddedScripts > ODatabaseModelImpl::getEmbeddedDocumentScripts() const
+{
+ return Reference< XEmbeddedScripts >( getModel_noCreate(), UNO_QUERY );
+}
+
+sal_Int16 ODatabaseModelImpl::getScriptingSignatureState()
+{
+ // no support for signatures at the moment
+ return SIGNATURESTATE_NOSIGNATURES;
+}
+
+sal_Bool ODatabaseModelImpl::hasTrustedScriptingSignature( sal_Bool /*bAllowUIToAddAuthor*/ )
+{
+ // no support for signatures at the moment
+ return sal_False;
+}
+
+void ODatabaseModelImpl::showBrokenSignatureWarning( const Reference< XInteractionHandler >& /*_rxInteraction*/ ) const
+{
+ OSL_ENSURE( false, "ODatabaseModelImpl::showBrokenSignatureWarning: signatures can't be broken - we do not support them!" );
+}
+
+void ODatabaseModelImpl::storageIsModified()
+{
+ setModified( sal_True );
+}
+
+ModelDependentComponent::ModelDependentComponent( const ::rtl::Reference< ODatabaseModelImpl >& _model )
+ :m_pImpl( _model )
+ ,m_aMutex( _model->getSharedMutex() )
+{
+}
+
+ModelDependentComponent::~ModelDependentComponent()
+{
+}
+
+} // namespace dbaccess
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/ModelImpl.hxx b/dbaccess/source/core/dataaccess/ModelImpl.hxx
new file mode 100644
index 000000000000..223654c38b85
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/ModelImpl.hxx
@@ -0,0 +1,644 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _DBA_COREDATAACCESS_MODELIMPL_HXX_
+#define _DBA_COREDATAACCESS_MODELIMPL_HXX_
+
+#include "apitools.hxx"
+#include "bookmarkcontainer.hxx"
+#include "ContentHelper.hxx"
+#include "core_resource.hxx"
+#include "documentevents.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertyAccess.hpp>
+#include <com/sun/star/container/XContainerListener.hpp>
+#include <com/sun/star/document/XDocumentSubStorageSupplier.hpp>
+#include <com/sun/star/document/XEventListener.hpp>
+#include <com/sun/star/document/XStorageBasedDocument.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/embed/XStorage.hpp>
+#include <com/sun/star/embed/XTransactionListener.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/lang/NotInitializedException.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/sdb/XBookmarksSupplier.hpp>
+#include <com/sun/star/sdb/XCompletedConnection.hpp>
+#include <com/sun/star/sdb/XFormDocumentsSupplier.hpp>
+#include <com/sun/star/sdb/XQueryDefinitionsSupplier.hpp>
+#include <com/sun/star/sdb/XReportDocumentsSupplier.hpp>
+#include <com/sun/star/sdbc/XDataSource.hpp>
+#include <com/sun/star/sdbc/XIsolatedConnection.hpp>
+#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
+#include <com/sun/star/util/XCloseable.hpp>
+#include <com/sun/star/util/XFlushable.hpp>
+#include <com/sun/star/util/XModifiable.hpp>
+#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
+#include <com/sun/star/util/XNumberFormatter.hpp>
+#include <com/sun/star/util/XRefreshable.hpp>
+#include <com/sun/star/sdb/XDocumentDataSource.hpp>
+#include <com/sun/star/frame/DoubleInitializationException.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/broadcasthelper.hxx>
+#include <comphelper/namedvaluecollection.hxx>
+#include <comphelper/proparrhlp.hxx>
+#include <comphelper/sharedmutex.hxx>
+#include <connectivity/CommonTools.hxx>
+#include <cppuhelper/propshlp.hxx>
+#include <cppuhelper/weakref.hxx>
+#include <sfx2/docmacromode.hxx>
+#include <sfx2/docstoragemodifylistener.hxx>
+#include <tools/string.hxx>
+#include <unotools/sharedunocomponent.hxx>
+#include <osl/mutex.hxx>
+#include <rtl/ref.hxx>
+
+#include <memory>
+
+namespace comphelper
+{
+ class NamedValueCollection;
+}
+
+//........................................................................
+namespace dbaccess
+{
+//........................................................................
+
+typedef ::com::sun::star::uno::WeakReference< ::com::sun::star::sdbc::XConnection > OWeakConnection;
+typedef std::vector< OWeakConnection > OWeakConnectionArray;
+
+struct AsciiPropertyValue
+{
+ // note: the canonic member order would be AsciiName / DefaultValue, but
+ // this crashes on unxlngi6.pro, since there's a bug which somehow results in
+ // getDefaultDataSourceSettings returning corrupted Any instances then.
+ ::com::sun::star::uno::Any DefaultValue;
+ const sal_Char* AsciiName;
+ const ::com::sun::star::uno::Type& ValueType;
+
+ AsciiPropertyValue()
+ :DefaultValue( )
+ ,AsciiName( NULL )
+ ,ValueType( ::cppu::UnoType< ::cppu::UnoVoidType >::get() )
+ {
+ }
+
+ AsciiPropertyValue( const sal_Char* _pAsciiName, const ::com::sun::star::uno::Any& _rDefaultValue )
+ :DefaultValue( _rDefaultValue )
+ ,AsciiName( _pAsciiName )
+ ,ValueType( _rDefaultValue.getValueType() )
+ {
+ OSL_ENSURE( ValueType.getTypeClass() != ::com::sun::star::uno::TypeClass_VOID,
+ "AsciiPropertyValue::AsciiPropertyValue: NULL values not allowed here, use the other CTOR for this!" );
+ }
+ AsciiPropertyValue( const sal_Char* _pAsciiName, const ::com::sun::star::uno::Type& _rValeType )
+ :DefaultValue()
+ ,AsciiName( _pAsciiName )
+ ,ValueType( _rValeType )
+ {
+ OSL_ENSURE( ValueType.getTypeClass() != ::com::sun::star::uno::TypeClass_VOID,
+ "AsciiPropertyValue::AsciiPropertyValue: VOID property values not supported!" );
+ }
+};
+
+class ODatabaseContext;
+class OSharedConnectionManager;
+
+//============================================================
+//= VosMutexFacade
+//============================================================
+/** a class which provides an IMutex interface to an OSL-based mutex
+*/
+class VosMutexFacade : public ::osl::SolarMutex
+{
+public:
+ /** beware of life time: the mutex you pass here must live as least as long
+ as the VosMutexFacade instance lives.
+ */
+ VosMutexFacade( ::osl::Mutex& _rMutex );
+
+ // IMutex
+ virtual void SAL_CALL acquire();
+ virtual sal_Bool SAL_CALL tryToAcquire();
+ virtual void SAL_CALL release();
+
+private:
+ ::osl::Mutex& m_rMutex;
+};
+
+
+//============================================================
+//= ODatabaseModelImpl
+//============================================================
+typedef ::utl::SharedUNOComponent< ::com::sun::star::embed::XStorage > SharedStorage;
+
+class ODatabaseContext;
+class DocumentStorageAccess;
+class OSharedConnectionManager;
+class ODatabaseModelImpl :public ::rtl::IReference
+ ,public ::sfx2::IMacroDocumentAccess
+ ,public ::sfx2::IModifiableDocument
+{
+public:
+ enum ObjectType
+ {
+ E_FORM = 0,
+ E_REPORT = 1,
+ E_QUERY = 2,
+ E_TABLE = 3
+ };
+
+ enum EmbeddedMacros
+ {
+ // the database document (storage) itself contains macros
+ eDocumentWideMacros,
+ // there are sub document( storage)s containing macros
+ eSubDocumentMacros,
+ // there are no known macro( storage)s
+ eNoMacros
+ };
+
+private:
+ OModuleClient m_aModuleClient;
+ ::com::sun::star::uno::WeakReference< ::com::sun::star::frame::XModel > m_xModel;
+ ::com::sun::star::uno::WeakReference< ::com::sun::star::sdbc::XDataSource > m_xDataSource;
+
+ DocumentStorageAccess* m_pStorageAccess;
+ ::comphelper::SharedMutex m_aMutex;
+ VosMutexFacade m_aMutexFacade;
+ ::std::vector< TContentPtr > m_aContainer; // one for each ObjectType
+ ::sfx2::DocumentMacroMode m_aMacroMode;
+ sal_Int16 m_nImposedMacroExecMode;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::script::XStorageBasedLibraryContainer > m_xBasicLibraries;
+ ::com::sun::star::uno::Reference< ::com::sun::star::script::XStorageBasedLibraryContainer > m_xDialogLibraries;
+
+ SharedStorage m_xDocumentStorage;
+ ::rtl::Reference< ::sfx2::DocumentStorageModifyListener > m_pStorageModifyListener;
+ ODatabaseContext* m_pDBContext;
+ DocumentEventsData m_aDocumentEvents;
+
+ ::comphelper::NamedValueCollection m_aMediaDescriptor;
+ /// the URL the document was loaded from
+ ::rtl::OUString m_sDocFileLocation;
+
+ oslInterlockedCount m_refCount;
+
+ /// do we have any object (forms/reports) which contains macros?
+ ::boost::optional< EmbeddedMacros > m_aEmbeddedMacros;
+
+ /// true if setting the Modified flag of the document is currently locked
+ bool m_bModificationLock;
+
+ /// true if and only if a database document existed previously (though meanwhile disposed), and was already initialized
+ bool m_bDocumentInitialized;
+
+ /** the URL which the document should report as it's URL
+
+ This might differ from ->m_sDocFileLocation in case the document was loaded
+ as part of a crash recovery process. In this case, ->m_sDocFileLocation points to
+ the temporary file where the DB had been saved to, after a crash.
+ ->m_sDocumentURL then is the URL of the document which actually had
+ been recovered.
+ */
+ ::rtl::OUString m_sDocumentURL;
+
+public:
+ OWeakConnectionArray m_aConnections;
+ const ::comphelper::ComponentContext m_aContext;
+
+public:
+ ::com::sun::star::uno::WeakReference< ::com::sun::star::container::XNameAccess > m_xCommandDefinitions;
+ ::com::sun::star::uno::WeakReference< ::com::sun::star::container::XNameAccess > m_xTableDefinitions;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier >
+ m_xNumberFormatsSupplier;
+ ::rtl::OUString m_sConnectURL;
+ ::rtl::OUString m_sName; // transient, our creator has to tell us the title
+ ::rtl::OUString m_sUser;
+ ::rtl::OUString m_aPassword; // transient !
+ ::rtl::OUString m_sFailedPassword;
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue>
+ m_aLayoutInformation;
+ sal_Int32 m_nLoginTimeout;
+ sal_Bool m_bReadOnly : 1;
+ sal_Bool m_bPasswordRequired : 1;
+ sal_Bool m_bSuppressVersionColumns : 1;
+ sal_Bool m_bModified : 1;
+ sal_Bool m_bDocumentReadOnly : 1;
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyAccess >
+ m_xSettings;
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > m_aTableFilter;
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > m_aTableTypeFilter;
+ OSharedConnectionManager* m_pSharedConnectionManager;
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >
+ m_xSharedConnectionManager;
+ sal_uInt16 m_nControllerLockCount;
+
+ void reset();
+
+ /** determines whether the database document has an embedded data storage
+ */
+ inline bool isEmbeddedDatabase() const { return ( m_sConnectURL.compareToAscii( "sdbc:embedded:", 14 ) == 0 ); }
+
+ /** stores the embedded storage ("database")
+
+ @param _bPreventRootCommits
+ Normally, committing the embedded storage results in also commiting the root storage
+ - this is an automatism for data safety reasons.
+ If you pass <TRUE/> here, committing the root storage is prevented for this particular
+ call.
+ @return <TRUE/> if the storage could be commited, otherwise <FALSE/>
+ */
+ bool commitEmbeddedStorage( bool _bPreventRootCommits = false );
+
+ /// commits all sub storages
+ void commitStorages()
+ SAL_THROW(( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException ));
+
+ ODatabaseModelImpl(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory,
+ ODatabaseContext& _pDBContext
+ );
+ virtual ~ODatabaseModelImpl();
+
+ ODatabaseModelImpl(
+ const ::rtl::OUString& _rRegistrationName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory,
+ ODatabaseContext& _rDBContext
+ );
+
+ // XEventListener
+ void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException);
+
+ void setModified( sal_Bool bModified );
+
+ void dispose();
+
+ inline ::rtl::OUString getURL() const { return m_sDocumentURL; }
+ inline ::rtl::OUString getDocFileLocation() const { return m_sDocFileLocation; }
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >
+ getStorage(
+ const ObjectType _eType, const sal_Int32 _nDesiredMode = ::com::sun::star::embed::ElementModes::READWRITE );
+
+// helper
+ const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier >&
+ getNumberFormatsSupplier();
+
+ DocumentEventsData&
+ getDocumentEvents() { return m_aDocumentEvents; }
+
+ const ::comphelper::NamedValueCollection&
+ getMediaDescriptor() const { return m_aMediaDescriptor; }
+
+ void setResource(
+ const ::rtl::OUString& _rURL,
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& _rArgs
+ );
+ void setDocFileLocation(
+ const ::rtl::OUString& i_rLoadedFrom
+ );
+
+ static ::comphelper::NamedValueCollection
+ stripLoadArguments( const ::comphelper::NamedValueCollection& _rArguments );
+
+// other stuff
+ void flushTables();
+
+ // disposes all elements in m_aStorages, and clears it
+ void disposeStorages() SAL_THROW(());
+
+ /// creates a ->com::sun::star::embed::StorageFactory
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XSingleServiceFactory >
+ createStorageFactory() const;
+
+ /// commits our storage
+ void commitRootStorage();
+
+ /// commits a given storage if it's not readonly, ignoring (but asserting) all errors
+ static bool commitStorageIfWriteable_ignoreErrors(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& _rxStorage
+ )
+ SAL_THROW(());
+
+ void clearConnections();
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > getOrCreateRootStorage();
+ inline ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > getRootStorage() const { return m_xDocumentStorage.getTyped(); }
+ inline void resetRootStroage() { impl_switchToStorage_throw( NULL ); }
+
+ /** returns the data source. If it doesn't exist it will be created
+ */
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDataSource> getOrCreateDataSource();
+
+ /** returns the model, if there already exists one
+ */
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > getModel_noCreate() const;
+
+ /** returns a new ->ODatabaseDocument
+
+ @param _bInitializeIfNecessary
+ calls XLoadable::initNew on the newly created model, if necessary
+
+ @precond
+ No ->ODatabaseDocument exists so far
+
+ @seealso
+ getModel_noCreate
+ */
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > createNewModel_deliverOwnership( bool _bInitialize );
+
+ struct ResetModelAccess { friend class ODatabaseDocument; private: ResetModelAccess() { } };
+
+ /** resets the model to NULL
+
+ Only to be called when the model is being disposed
+ */
+ void modelIsDisposing( const bool _wasInitialized, ResetModelAccess );
+
+ bool hadInitializedDocument() const { return m_bDocumentInitialized; }
+
+ DocumentStorageAccess*
+ getDocumentStorageAccess();
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::document::XDocumentSubStorageSupplier >
+ getDocumentSubStorageSupplier();
+
+ inline const ::comphelper::SharedMutex& getSharedMutex() const { return m_aMutex; }
+
+ /** @see osl_incrementInterlockedCount.
+ */
+ virtual oslInterlockedCount SAL_CALL acquire();
+
+ /** @see osl_decrementInterlockedCount.
+ */
+ virtual oslInterlockedCount SAL_CALL release();
+
+ /// returns a all known data source settings, including their default values
+ static const AsciiPropertyValue* getDefaultDataSourceSettings();
+
+ /** retrieves the requested container of objects (forms/reports/tables/queries)
+ */
+ TContentPtr& getObjectContainer( const ObjectType _eType );
+
+ /** returns the name of the storage which is used to stored objects of the given type, if applicable
+ */
+ static ::rtl::OUString
+ getObjectContainerStorageName( const ObjectType _eType );
+
+ /** revokes the data source registration at the database context
+ */
+ void revokeDataSource() const;
+
+ /** determines whether a given object storage contains macros
+ */
+ static bool objectHasMacros(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& _rxContainerStorage,
+ const ::rtl::OUString& _rPersistentName
+ );
+
+ /** determines which kind of embedded macros are present in the document
+ */
+ EmbeddedMacros determineEmbeddedMacros();
+
+ /** checks our document's macro execution mode, using the interaction handler as supplied with our
+ load arguments
+ */
+ bool checkMacrosOnLoading();
+
+ /** adjusts our document's macro execution mode, without using any UI, assuming the user
+ would reject execution of macros, if she would have been asked.
+
+ If checkMacrosOnLoading has been called before (and thus the macro execution mode
+ is already adjusted), then the current execution mode is simply returned.
+
+ @return
+ whether or not macro execution is allowed
+ */
+ bool adjustMacroMode_AutoReject();
+
+ /** resets our macro execute mode, so next time the checkMacrosOnLoading is called, it will
+ behave as if it has never been called before
+ */
+ void resetMacroExecutionMode();
+
+ /** ensures that ->m_xBasicLibraries resp. m_xDialogLibraries exists
+
+ @return
+ the requested library container. Is never <NULL/>.
+
+ @throws RuntimeException
+ if something does wrong, which indicates a server error in the installation
+ */
+ ::com::sun::star::uno::Reference< ::com::sun::star::script::XStorageBasedLibraryContainer >
+ getLibraryContainer( bool _bScript );
+
+ /** lets our library containers store themself into the given root storage
+ */
+ void storeLibraryContainersTo( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& _rxToRootStorage );
+
+ /** rebases the document to the given storage
+
+ No actual committing, copying, saving, whatsoever happens. The storage is just remembered as the documents
+ new storage, nothing more.
+
+ @throws ::com::sun::star::lang::IllegalArgumentException
+ if the given storage is <NULL/>
+ @throws ::com::sun::star::lang::RuntimeException
+ if any of the invoked operations does so
+ */
+ ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >
+ switchToStorage(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& _rxNewRootStorage
+ );
+
+ /** returns the macro mode imposed by an external instance, which passed it to attachResource
+ */
+ sal_Int16 getImposedMacroExecMode() const
+ {
+ return m_nImposedMacroExecMode;
+ }
+ void setImposedMacroExecMode( const sal_Int16 _nMacroMode )
+ {
+ m_nImposedMacroExecMode = _nMacroMode;
+ }
+
+public:
+ // IMacroDocumentAccess overridables
+ virtual sal_Int16 getCurrentMacroExecMode() const;
+ virtual sal_Bool setCurrentMacroExecMode( sal_uInt16 );
+ virtual ::rtl::OUString getDocumentLocation() const;
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > getZipStorageToSign();
+ virtual sal_Bool documentStorageHasMacros() const;
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::document::XEmbeddedScripts > getEmbeddedDocumentScripts() const;
+ virtual sal_Int16 getScriptingSignatureState();
+ virtual sal_Bool hasTrustedScriptingSignature( sal_Bool bAllowUIToAddAuthor );
+ virtual void showBrokenSignatureWarning( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& _rxInteraction ) const;
+
+ // IModifiableDocument
+ virtual void storageIsModified();
+
+ // don't use directly, use the ModifyLock class instead
+ void lockModify() { m_bModificationLock = true; }
+ void unlockModify() { m_bModificationLock = false; }
+ bool isModifyLocked() const { return m_bModificationLock; }
+
+private:
+ void impl_construct_nothrow();
+ ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >
+ impl_switchToStorage_throw( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& _rxNewRootStorage );
+
+ /** switches to the given document URL, which denotes the logical URL of the document, not necessariy the
+ URL where the doc was loaded/recovered from
+ */
+ void impl_switchToLogicalURL(
+ const ::rtl::OUString& i_rDocumentURL
+ );
+
+};
+
+/** a small base class for UNO components whose functionality depends on a ODatabaseModelImpl
+*/
+class ModelDependentComponent
+{
+protected:
+ ::rtl::Reference< ODatabaseModelImpl > m_pImpl;
+ mutable ::comphelper::SharedMutex m_aMutex;
+
+protected:
+ ModelDependentComponent( const ::rtl::Reference< ODatabaseModelImpl >& _model );
+ virtual ~ModelDependentComponent();
+
+ /** returns the component itself
+ */
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > getThis() const = 0;
+
+ inline ::osl::Mutex& getMutex() const
+ {
+ return m_aMutex;
+ }
+
+public:
+ struct GuardAccess { friend class ModelMethodGuard; private: GuardAccess() { } };
+
+ /** returns the mutex used for thread safety
+
+ @throws ::com::sun::star::lang::DisposedException
+ if m_pImpl is <NULL/>. Usually, you will set this member in your derived
+ component's <code>dispose</code> method to <NULL/>.
+ */
+ inline ::osl::Mutex& getMutex( GuardAccess ) const
+ {
+ return getMutex();
+ }
+ inline ::rtl::Reference< ODatabaseModelImpl > getImpl( GuardAccess )
+ {
+ return m_pImpl;
+ }
+
+ /// checks whether the component is already disposed, throws a DisposedException if so
+ inline void checkDisposed() const
+ {
+ if ( !m_pImpl.is() )
+ throw ::com::sun::star::lang::DisposedException( ::rtl::OUString::createFromAscii( "Component is already disposed." ), getThis() );
+ }
+
+ inline void lockModify()
+ {
+ m_pImpl->lockModify();
+ }
+
+ inline void unlockModify()
+ {
+ m_pImpl->unlockModify();
+ }
+};
+
+class ModifyLock
+{
+public:
+ ModifyLock( ModelDependentComponent& _component )
+ :m_rComponent( _component )
+ {
+ m_rComponent.lockModify();
+ }
+
+ ~ModifyLock()
+ {
+ m_rComponent.unlockModify();
+ }
+
+private:
+ ModelDependentComponent& m_rComponent;
+};
+
+/** a guard for public methods of objects dependent on a ODatabaseModelImpl instance
+
+ Just put this guard onto the stack at the beginning of your method. Don't bother yourself
+ with a MutexGuard, checks for being disposed, and the like.
+*/
+class ModelMethodGuard : public ::osl::ResettableMutexGuard
+{
+private:
+ typedef ::osl::ResettableMutexGuard BaseMutexGuard;
+
+public:
+ /** constructs the guard
+
+ @param _component
+ the component whose functionality depends on a ODatabaseModelImpl instance
+
+ @throws ::com::sun::star::lang::DisposedException
+ If the given component is already disposed
+ */
+ ModelMethodGuard( const ModelDependentComponent& _component )
+ :BaseMutexGuard( _component.getMutex( ModelDependentComponent::GuardAccess() ) )
+ {
+ _component.checkDisposed();
+ }
+
+ ~ModelMethodGuard()
+ {
+ }
+};
+
+//........................................................................
+} // namespace dbaccess
+//........................................................................
+
+#endif // _DBA_COREDATAACCESS_DATALINK_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/SharedConnection.cxx b/dbaccess/source/core/dataaccess/SharedConnection.cxx
new file mode 100644
index 000000000000..eaa2628648f2
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/SharedConnection.cxx
@@ -0,0 +1,168 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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"
+#include "SharedConnection.hxx"
+#include <tools/debug.hxx>
+
+
+namespace dbaccess
+{
+ using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::container;
+// using namespace ::com::sun::star::reflection;
+using namespace connectivity;
+
+DBG_NAME(OSharedConnection)
+OSharedConnection::OSharedConnection(Reference< XAggregation >& _rxProxyConnection)
+ : OSharedConnection_BASE(m_aMutex)
+{
+ DBG_CTOR(OSharedConnection,NULL);
+ setDelegation(_rxProxyConnection,m_refCount);
+}
+
+OSharedConnection::~OSharedConnection()
+{
+ DBG_DTOR(OSharedConnection,NULL);
+}
+
+void SAL_CALL OSharedConnection::disposing(void)
+{
+ OSharedConnection_BASE::disposing();
+ OConnectionWrapper::disposing();
+}
+
+Reference< XStatement > SAL_CALL OSharedConnection::createStatement( ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(rBHelper.bDisposed);
+
+ return m_xConnection->createStatement();
+}
+
+Reference< XPreparedStatement > SAL_CALL OSharedConnection::prepareStatement( const ::rtl::OUString& sql ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(rBHelper.bDisposed);
+
+ return m_xConnection->prepareStatement(sql);
+}
+
+Reference< XPreparedStatement > SAL_CALL OSharedConnection::prepareCall( const ::rtl::OUString& sql ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(rBHelper.bDisposed);
+
+ return m_xConnection->prepareCall(sql);
+}
+
+::rtl::OUString SAL_CALL OSharedConnection::nativeSQL( const ::rtl::OUString& sql ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(rBHelper.bDisposed);
+
+ return m_xConnection->nativeSQL(sql);
+}
+
+sal_Bool SAL_CALL OSharedConnection::getAutoCommit( ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(rBHelper.bDisposed);
+
+ return m_xConnection->getAutoCommit();
+}
+
+void SAL_CALL OSharedConnection::commit( ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(rBHelper.bDisposed);
+
+ m_xConnection->commit();
+}
+
+void SAL_CALL OSharedConnection::rollback( ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(rBHelper.bDisposed);
+
+ m_xConnection->rollback();
+}
+
+sal_Bool SAL_CALL OSharedConnection::isClosed( ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ return m_xConnection->isClosed();
+}
+
+Reference< XDatabaseMetaData > SAL_CALL OSharedConnection::getMetaData( ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(rBHelper.bDisposed);
+
+
+ return m_xConnection->getMetaData();
+}
+
+sal_Bool SAL_CALL OSharedConnection::isReadOnly( ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(rBHelper.bDisposed);
+
+ return m_xConnection->isReadOnly();
+}
+
+::rtl::OUString SAL_CALL OSharedConnection::getCatalog( ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(rBHelper.bDisposed);
+
+ return m_xConnection->getCatalog();
+}
+
+sal_Int32 SAL_CALL OSharedConnection::getTransactionIsolation( ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(rBHelper.bDisposed);
+
+ return m_xConnection->getTransactionIsolation();
+}
+
+Reference< ::com::sun::star::container::XNameAccess > SAL_CALL OSharedConnection::getTypeMap( ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(rBHelper.bDisposed);
+
+ return m_xConnection->getTypeMap();
+}
+
+} // namespace dbaccess
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/SharedConnection.hxx b/dbaccess/source/core/dataaccess/SharedConnection.hxx
new file mode 100644
index 000000000000..4d21609d8d2c
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/SharedConnection.hxx
@@ -0,0 +1,144 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef DBA_CORE_SHARED_CONNECTION_HXX
+#define DBA_CORE_SHARED_CONNECTION_HXX
+
+#include "connectivity/ConnectionWrapper.hxx"
+#include <cppuhelper/component.hxx>
+#include <connectivity/CommonTools.hxx>
+#include <cppuhelper/compbase1.hxx>
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <com/sun/star/sdbc/XWarningsSupplier.hpp>
+#include <com/sun/star/sdbc/SQLWarning.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/sdb/XSQLQueryComposerFactory.hpp>
+#include <com/sun/star/sdb/XCommandPreparation.hpp>
+#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
+#include <com/sun/star/sdbcx/XViewsSupplier.hpp>
+#include <com/sun/star/sdb/XQueriesSupplier.hpp>
+#include <comphelper/sequence.hxx>
+
+
+namespace dbaccess
+{
+ //=======================================================================================
+ //= OSharedConnection: This class implements a simple forwarding of connection calls.
+ //= All methods will be forwarded with exception of the set methods, which are not allowed
+ //= to be called on shared connections. Instances of this class will be created when the
+ //= datasource is asked for not isolated connection.
+ //=======================================================================================
+ typedef ::cppu::WeakComponentImplHelper1< ::com::sun::star::sdbc::XConnection
+ > OSharedConnection_BASE;
+ typedef ::connectivity::OConnectionWrapper OSharedConnection_BASE2;
+
+ class OSharedConnection : public ::comphelper::OBaseMutex
+ , public OSharedConnection_BASE
+ , public OSharedConnection_BASE2
+ {
+ protected:
+ virtual void SAL_CALL disposing(void);
+ virtual ~OSharedConnection();
+ public:
+ OSharedConnection(::com::sun::star::uno::Reference< ::com::sun::star::uno::XAggregation >& _rxProxyConnection);
+
+ virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId( ) throw (::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL acquire() throw() { OSharedConnection_BASE::acquire(); }
+ virtual void SAL_CALL release() throw() { OSharedConnection_BASE::release(); }
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes( ) throw (::com::sun::star::uno::RuntimeException)
+ {
+ return ::comphelper::concatSequences(
+ OSharedConnection_BASE::getTypes(),
+ OSharedConnection_BASE2::getTypes()
+ );
+ }
+
+ virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& _rType ) throw (::com::sun::star::uno::RuntimeException)
+ {
+ ::com::sun::star::uno::Any aReturn = OSharedConnection_BASE::queryInterface(_rType);
+ if ( !aReturn.hasValue() )
+ aReturn = OSharedConnection_BASE2::queryInterface(_rType);
+ return aReturn;
+ }
+
+ // XCloseable
+ virtual void SAL_CALL close( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
+ {
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ ::connectivity::checkDisposed(rBHelper.bDisposed);
+ }
+ dispose();
+ }
+
+ // XConnection
+ virtual void SAL_CALL setAutoCommit( sal_Bool /*autoCommit*/ ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
+ {
+ throw ::com::sun::star::sdbc::SQLException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("This call is not allowed when sharing connections.")),*this,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("S10000")),0,::com::sun::star::uno::Any());
+ }
+ virtual void SAL_CALL setReadOnly( sal_Bool /*readOnly*/ ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
+ {
+ throw ::com::sun::star::sdbc::SQLException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("This call is not allowed when sharing connections.")),*this,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("S10000")),0,::com::sun::star::uno::Any());
+ }
+ virtual void SAL_CALL setCatalog( const ::rtl::OUString& /*catalog*/ ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
+ {
+ throw ::com::sun::star::sdbc::SQLException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("This call is not allowed when sharing connections.")),*this,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("S10000")),0,::com::sun::star::uno::Any());
+ }
+ virtual void SAL_CALL setTransactionIsolation( sal_Int32 /*level*/ ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
+ {
+ throw ::com::sun::star::sdbc::SQLException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("This call is not allowed when sharing connections.")),*this,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("S10000")),0,::com::sun::star::uno::Any());
+ }
+ virtual void SAL_CALL setTypeMap( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& /*typeMap*/ ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
+ {
+ throw ::com::sun::star::sdbc::SQLException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("This call is not allowed when sharing connections.")),*this,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("S10000")),0,::com::sun::star::uno::Any());
+ }
+ // XConnection
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XStatement > SAL_CALL createStatement( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XPreparedStatement > SAL_CALL prepareStatement( const ::rtl::OUString& sql ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XPreparedStatement > SAL_CALL prepareCall( const ::rtl::OUString& sql ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL nativeSQL( const ::rtl::OUString& sql ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL getAutoCommit( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL commit( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL rollback( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL isClosed( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData > SAL_CALL getMetaData( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL isReadOnly( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getCatalog( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getTransactionIsolation( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL getTypeMap( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ };
+
+#ifdef IMPLEMENT_GET_IMPLEMENTATION_ID
+ IMPLEMENT_GET_IMPLEMENTATION_ID( OSharedConnection );
+#endif
+
+} // namespace dbaccess
+
+#endif // DBA_CORE_SHARED_CONNECTION_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/bookmarkcontainer.cxx b/dbaccess/source/core/dataaccess/bookmarkcontainer.cxx
new file mode 100644
index 000000000000..9caf1a583dc7
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/bookmarkcontainer.cxx
@@ -0,0 +1,371 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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"
+
+#include "bookmarkcontainer.hxx"
+#include "dbastrings.hrc"
+#include "apitools.hxx"
+#include "core_resource.hxx"
+#include "core_resource.hrc"
+
+#include <tools/debug.hxx>
+#include <comphelper/sequence.hxx>
+#include <comphelper/enumhelper.hxx>
+#include <comphelper/extract.hxx>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <comphelper/types.hxx>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::osl;
+using namespace ::comphelper;
+using namespace ::cppu;
+
+namespace dbaccess
+{
+
+//==========================================================================
+//= OBookmarkContainer
+//==========================================================================
+DBG_NAME(OBookmarkContainer)
+
+OBookmarkContainer::OBookmarkContainer(OWeakObject& _rParent, Mutex& _rMutex)
+ :m_rParent(_rParent)
+ ,m_aContainerListeners(_rMutex)
+ ,m_rMutex(_rMutex)
+{
+ DBG_CTOR(OBookmarkContainer, NULL);
+}
+
+void OBookmarkContainer::dispose()
+{
+ MutexGuard aGuard(m_rMutex);
+
+ // say our listeners goobye
+ EventObject aEvt(*this);
+ m_aContainerListeners.disposeAndClear(aEvt);
+
+ // remove our elements
+ m_aBookmarksIndexed.clear();
+ m_aBookmarks.clear();
+}
+
+void SAL_CALL OBookmarkContainer::acquire( ) throw()
+{
+ m_rParent.acquire();
+}
+
+void SAL_CALL OBookmarkContainer::release( ) throw()
+{
+ m_rParent.release();
+}
+
+OBookmarkContainer::~OBookmarkContainer()
+{
+ DBG_DTOR(OBookmarkContainer, NULL);
+}
+
+// XServiceInfo
+::rtl::OUString SAL_CALL OBookmarkContainer::getImplementationName( ) throw(RuntimeException)
+{
+ return ::rtl::OUString::createFromAscii("com.sun.star.comp.dba.OBookmarkContainer");
+}
+
+sal_Bool SAL_CALL OBookmarkContainer::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException)
+{
+ MutexGuard aGuard(m_rMutex);
+ checkValid(sal_False);
+ return findValue(getSupportedServiceNames(), _rServiceName, sal_True).getLength() != 0;
+}
+
+Sequence< ::rtl::OUString > SAL_CALL OBookmarkContainer::getSupportedServiceNames( ) throw(RuntimeException)
+{
+ Sequence< ::rtl::OUString > aReturn(1);
+ aReturn.getArray()[0] = ::rtl::OUString::createFromAscii("com.sun.star.sdb.DefinitionContainer");
+ return aReturn;
+}
+
+// XNameContainer
+void SAL_CALL OBookmarkContainer::insertByName( const ::rtl::OUString& _rName, const Any& aElement ) throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
+{
+ MutexGuard aGuard(m_rMutex);
+ checkValid(sal_True);
+
+ if (checkExistence(_rName))
+ throw ElementExistException();
+
+ if (0 == _rName.getLength())
+ throw IllegalArgumentException();
+
+ // approve the new object
+ ::rtl::OUString sNewLink;
+ if (!(aElement >>= sNewLink))
+ throw IllegalArgumentException();
+
+
+ implAppend(_rName, sNewLink);
+
+ // notify the listeners
+ if (m_aContainerListeners.getLength())
+ {
+ ContainerEvent aEvent(*this, makeAny(_rName), makeAny(sNewLink), Any());
+ OInterfaceIteratorHelper aListenerIterator(m_aContainerListeners);
+ while (aListenerIterator.hasMoreElements())
+ static_cast< XContainerListener* >(aListenerIterator.next())->elementInserted(aEvent);
+ }
+}
+
+void SAL_CALL OBookmarkContainer::removeByName( const ::rtl::OUString& _rName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ ::rtl::OUString sOldBookmark;
+ {
+ MutexGuard aGuard(m_rMutex);
+ checkValid(sal_True);
+
+ // check the arguments
+ if (!_rName.getLength())
+ throw IllegalArgumentException();
+
+ if (!checkExistence(_rName))
+ throw NoSuchElementException();
+
+ // the old element (for the notifications)
+ sOldBookmark = m_aBookmarks[_rName];
+
+ // do the removal
+ implRemove(_rName);
+ }
+
+ // notify the listeners
+ if (m_aContainerListeners.getLength())
+ {
+ ContainerEvent aEvent(*this, makeAny(_rName), makeAny(sOldBookmark), Any());
+ OInterfaceIteratorHelper aListenerIterator(m_aContainerListeners);
+ while (aListenerIterator.hasMoreElements())
+ static_cast< XContainerListener* >(aListenerIterator.next())->elementRemoved(aEvent);
+ }
+}
+
+// XNameReplace
+void SAL_CALL OBookmarkContainer::replaceByName( const ::rtl::OUString& _rName, const Any& aElement ) throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ ClearableMutexGuard aGuard(m_rMutex);
+ checkValid(sal_True);
+
+ // check the arguments
+ if (!_rName.getLength())
+ throw IllegalArgumentException();
+
+ // do we have such an element?
+ if (!checkExistence(_rName))
+ throw NoSuchElementException();
+
+ // approve the new object
+ ::rtl::OUString sNewLink;
+ if (!(aElement >>= sNewLink))
+ throw IllegalArgumentException();
+
+ // the old element (for the notifications)
+ ::rtl::OUString sOldLink = m_aBookmarks[_rName];
+
+ // do the replace
+ implReplace(_rName, sNewLink);
+
+ // notify the listeners
+ aGuard.clear();
+ if (m_aContainerListeners.getLength())
+ {
+ ContainerEvent aEvent(*this, makeAny(_rName), makeAny(sNewLink), makeAny(sOldLink));
+ OInterfaceIteratorHelper aListenerIterator(m_aContainerListeners);
+ while (aListenerIterator.hasMoreElements())
+ static_cast< XContainerListener* >(aListenerIterator.next())->elementReplaced(aEvent);
+ }
+}
+
+void SAL_CALL OBookmarkContainer::addContainerListener( const Reference< XContainerListener >& _rxListener ) throw(RuntimeException)
+{
+ MutexGuard aGuard(m_rMutex);
+ if (_rxListener.is())
+ m_aContainerListeners.addInterface(_rxListener);
+}
+
+void SAL_CALL OBookmarkContainer::removeContainerListener( const Reference< XContainerListener >& _rxListener ) throw(RuntimeException)
+{
+ MutexGuard aGuard(m_rMutex);
+ if (_rxListener.is())
+ m_aContainerListeners.removeInterface(_rxListener);
+}
+
+// XElementAccess
+Type SAL_CALL OBookmarkContainer::getElementType( ) throw (RuntimeException)
+{
+ MutexGuard aGuard(m_rMutex);
+ checkValid(sal_False);
+ return ::getCppuType( static_cast< ::rtl::OUString* >(NULL) );
+}
+
+sal_Bool SAL_CALL OBookmarkContainer::hasElements( ) throw (RuntimeException)
+{
+ MutexGuard aGuard(m_rMutex);
+ checkValid(sal_False);
+ return !m_aBookmarks.empty();
+}
+
+// XEnumerationAccess
+Reference< XEnumeration > SAL_CALL OBookmarkContainer::createEnumeration( ) throw(RuntimeException)
+{
+ MutexGuard aGuard(m_rMutex);
+ checkValid(sal_False);
+ return new ::comphelper::OEnumerationByIndex(static_cast<XIndexAccess*>(this));
+}
+
+// XIndexAccess
+sal_Int32 SAL_CALL OBookmarkContainer::getCount( ) throw(RuntimeException)
+{
+ MutexGuard aGuard(m_rMutex);
+ checkValid(sal_False);
+ return m_aBookmarks.size();
+}
+
+Any SAL_CALL OBookmarkContainer::getByIndex( sal_Int32 _nIndex ) throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
+{
+ MutexGuard aGuard(m_rMutex);
+ checkValid(sal_False);
+
+ if ((_nIndex < 0) || (_nIndex >= (sal_Int32)m_aBookmarksIndexed.size()))
+ throw IndexOutOfBoundsException();
+
+ return makeAny(m_aBookmarksIndexed[_nIndex]->second);
+}
+
+Any SAL_CALL OBookmarkContainer::getByName( const ::rtl::OUString& _rName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ MutexGuard aGuard(m_rMutex);
+ checkValid(sal_False);
+
+ if (!checkExistence(_rName))
+ throw NoSuchElementException();
+
+ return makeAny(m_aBookmarks[_rName]);
+}
+
+Sequence< ::rtl::OUString > SAL_CALL OBookmarkContainer::getElementNames( ) throw(RuntimeException)
+{
+ MutexGuard aGuard(m_rMutex);
+ checkValid(sal_False);
+
+ Sequence< ::rtl::OUString > aNames(m_aBookmarks.size());
+ ::rtl::OUString* pNames = aNames.getArray();
+ ;
+ for ( ConstMapIteratorVectorIterator aNameIter = m_aBookmarksIndexed.begin();
+ aNameIter != m_aBookmarksIndexed.end();
+ ++pNames, ++aNameIter
+ )
+ {
+ *pNames = (*aNameIter)->first;
+ }
+
+ return aNames;
+}
+
+sal_Bool SAL_CALL OBookmarkContainer::hasByName( const ::rtl::OUString& _rName ) throw(RuntimeException)
+{
+ MutexGuard aGuard(m_rMutex);
+ checkValid(sal_False);
+
+ return checkExistence(_rName);
+}
+
+void OBookmarkContainer::implRemove(const ::rtl::OUString& _rName)
+{
+ MutexGuard aGuard(m_rMutex);
+
+ // look for the name in the index access vector
+ MapString2StringIterator aMapPos = m_aBookmarks.end();
+ for ( MapIteratorVectorIterator aSearch = m_aBookmarksIndexed.begin();
+ aSearch != m_aBookmarksIndexed.end();
+ ++aSearch
+ )
+ {
+#ifdef DBG_UTIL
+ ::rtl::OUString sName = (*aSearch)->first;
+#endif
+ if ((*aSearch)->first == _rName)
+ {
+ aMapPos = *aSearch;
+ m_aBookmarksIndexed.erase(aSearch);
+ break;
+ }
+ }
+
+ if (m_aBookmarks.end() == aMapPos)
+ {
+ DBG_ERROR("OBookmarkContainer::implRemove: inconsistence!");
+ return;
+ }
+
+ // remove the map entries
+ m_aBookmarks.erase(aMapPos);
+}
+
+void OBookmarkContainer::implAppend(const ::rtl::OUString& _rName, const ::rtl::OUString& _rDocumentLocation)
+{
+ MutexGuard aGuard(m_rMutex);
+
+ OSL_ENSURE(m_aBookmarks.find(_rName) == m_aBookmarks.end(),"Bookmark already known!");
+ m_aBookmarksIndexed.push_back(m_aBookmarks.insert( MapString2String::value_type(_rName,_rDocumentLocation)).first);
+}
+
+void OBookmarkContainer::implReplace(const ::rtl::OUString& _rName, const ::rtl::OUString& _rNewLink)
+{
+ MutexGuard aGuard(m_rMutex);
+ DBG_ASSERT(checkExistence(_rName), "OBookmarkContainer::implReplace : invalid name !");
+
+ m_aBookmarks[_rName] = _rNewLink;
+}
+
+void OBookmarkContainer::checkValid(sal_Bool /*_bIntendWriteAccess*/) const throw (RuntimeException, DisposedException)
+{
+}
+
+Reference< XInterface > SAL_CALL OBookmarkContainer::getParent( ) throw (RuntimeException)
+{
+ return m_rParent;
+}
+
+void SAL_CALL OBookmarkContainer::setParent( const Reference< XInterface >& /*Parent*/ ) throw (NoSupportException, RuntimeException)
+{
+ throw NoSupportException();
+}
+
+} // namespace dbaccess
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/bookmarkcontainer.hxx b/dbaccess/source/core/dataaccess/bookmarkcontainer.hxx
new file mode 100644
index 000000000000..648d5654d114
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/bookmarkcontainer.hxx
@@ -0,0 +1,179 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _DBA_CORE_BOOKMARKCONTAINER_HXX_
+#define _DBA_CORE_BOOKMARKCONTAINER_HXX_
+
+#include <cppuhelper/interfacecontainer.hxx>
+#include <cppuhelper/implbase6.hxx>
+#include <comphelper/stl_types.hxx>
+#include <osl/mutex.hxx>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XContainer.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+
+namespace dbaccess
+{
+
+//==========================================================================
+//= OBookmarkContainer - base class of collections of database definition
+//= documents
+//==========================================================================
+typedef ::cppu::WeakImplHelper6 <
+ ::com::sun::star::container::XIndexAccess
+ , ::com::sun::star::container::XNameContainer
+ , ::com::sun::star::container::XEnumerationAccess
+ , ::com::sun::star::container::XContainer
+ , ::com::sun::star::lang::XServiceInfo
+ , ::com::sun::star::container::XChild
+ > OBookmarkContainer_Base;
+
+class OBookmarkContainer
+ :public OBookmarkContainer_Base
+{
+protected:
+ DECLARE_STL_USTRINGACCESS_MAP(::rtl::OUString, MapString2String);
+ DECLARE_STL_VECTOR(MapString2StringIterator, MapIteratorVector);
+
+ MapString2String m_aBookmarks; // the bookmarks itself
+ MapIteratorVector m_aBookmarksIndexed; // for index access to the
+
+protected:
+ ::cppu::OWeakObject& m_rParent; // for the ref counting
+ ::cppu::OInterfaceContainerHelper
+ m_aContainerListeners;
+ ::osl::Mutex& m_rMutex;
+
+
+public:
+ /** constructs the container.<BR>
+ after the construction of the object the creator has to call <code>initialize</code>.
+ @param _rParent the parent object which is used for ref counting
+ @param _rMutex the parent's mutex object for access safety
+ */
+ OBookmarkContainer(
+ ::cppu::OWeakObject& _rParent,
+ ::osl::Mutex& _rMutex
+ );
+
+ /** looks like the dtor ...
+ */
+ virtual ~OBookmarkContainer();
+
+// ::com::sun::star::uno::XInterface
+ virtual void SAL_CALL acquire( ) throw();
+ virtual void SAL_CALL release( ) throw();
+
+// ::com::sun::star::lang::XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException);
+
+// ::com::sun::star::container::XElementAccess
+ virtual ::com::sun::star::uno::Type SAL_CALL getElementType( ) throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasElements( ) throw(::com::sun::star::uno::RuntimeException);
+
+// ::com::sun::star::container::XEnumerationAccess
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumeration > SAL_CALL createEnumeration( ) throw(::com::sun::star::uno::RuntimeException);
+
+// ::com::sun::star::container::XIndexAccess
+ virtual sal_Int32 SAL_CALL getCount( ) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Any SAL_CALL getByIndex( sal_Int32 _nIndex ) throw(::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+// ::com::sun::star::container::XNameContainer
+ virtual void SAL_CALL insertByName( const ::rtl::OUString& _rName, const ::com::sun::star::uno::Any& aElement ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeByName( const ::rtl::OUString& _rName ) throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+// ::com::sun::star::container::XNameReplace
+ virtual void SAL_CALL replaceByName( const ::rtl::OUString& _rName, const ::com::sun::star::uno::Any& aElement ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+// ::com::sun::star::container::XNameAccess
+ virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( ) throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw(::com::sun::star::uno::RuntimeException);
+
+// ::com::sun::star::container::XContainer
+ virtual void SAL_CALL addContainerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener >& xListener ) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeContainerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener >& xListener ) throw(::com::sun::star::uno::RuntimeException);
+
+// ::com::sun::star::container::XChild
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL getParent( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setParent( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& Parent ) throw (::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException);
+
+// helper
+ /** tell the container to free all resources. After that it's in a state like after the construction, i.e.
+ you may call <code>initialize</code> again (maybe with another configuration node).
+ */
+ virtual void dispose();
+
+
+protected:
+ /** checks whether the object is basically alive, i.e. it has been fully initialized (@see initialize) and
+ not disposed (@see dispose)
+ @param _bIntendWriteAccess determines whether or not the caller intends to modify the configuration.
+ if sal_True and the configuration is readonly, a runtime exception with
+ a description string is thrown.
+ */
+ void checkValid(sal_Bool _bIntendWriteAccess) const throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::DisposedException);
+
+ /** quickly checks if there already is an element with a given name. No access to the configuration occures, i.e.
+ if there is such an object which is not already loaded, it won't be loaded now.
+ @param _rName the object name to check
+ @return sal_True if there already exists such an object
+ */
+ inline sal_Bool checkExistence(const ::rtl::OUString& _rName);
+
+ void implAppend(
+ const ::rtl::OUString& _rName,
+ const ::rtl::OUString& _rDocumentLocation
+ );
+
+ void implRemove(const ::rtl::OUString& _rName);
+
+ void implReplace(
+ const ::rtl::OUString& _rName,
+ const ::rtl::OUString& _rNewLink);
+
+};
+
+inline sal_Bool OBookmarkContainer::checkExistence(const ::rtl::OUString& _rName)
+{
+ return m_aBookmarks.find(_rName) != m_aBookmarks.end();
+}
+
+} // namespace dbaccess
+
+#endif // _DBA_CORE_BOOKMARKCONTAINER_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/commandcontainer.cxx b/dbaccess/source/core/dataaccess/commandcontainer.cxx
new file mode 100644
index 000000000000..3394cd0f0ca4
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/commandcontainer.cxx
@@ -0,0 +1,101 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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"
+
+#include "commandcontainer.hxx"
+#include "commanddefinition.hxx"
+
+#include <tools/debug.hxx>
+#include "dbastrings.hrc"
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::ucb;
+using namespace ::osl;
+using namespace ::comphelper;
+using namespace ::cppu;
+
+namespace dbaccess
+{
+
+//==========================================================================
+//= OCommandContainer
+//==========================================================================
+DBG_NAME(OCommandContainer)
+
+OCommandContainer::OCommandContainer( const Reference< ::com::sun::star::lang::XMultiServiceFactory >& _xORB
+ ,const Reference< XInterface >& _xParentContainer
+ ,const TContentPtr& _pImpl
+ ,sal_Bool _bTables
+ )
+ :ODefinitionContainer(_xORB,_xParentContainer,_pImpl,!_bTables)
+ ,m_bTables(_bTables)
+{
+ DBG_CTOR(OCommandContainer, NULL);
+}
+
+OCommandContainer::~OCommandContainer()
+{
+ DBG_DTOR(OCommandContainer, NULL);
+}
+
+IMPLEMENT_FORWARD_XINTERFACE2( OCommandContainer,ODefinitionContainer,OCommandContainer_BASE)
+IMPLEMENT_TYPEPROVIDER2(OCommandContainer,ODefinitionContainer,OCommandContainer_BASE);
+
+Reference< XContent > OCommandContainer::createObject( const ::rtl::OUString& _rName)
+{
+ const ODefinitionContainer_Impl& rDefinitions( getDefinitions() );
+ OSL_ENSURE( rDefinitions.find(_rName) != rDefinitions.end(), "OCommandContainer::createObject: Invalid entry in map!" );
+
+ const TContentPtr& pElementContent( rDefinitions.find( _rName )->second );
+ if ( m_bTables )
+ return new OComponentDefinition( *this, _rName, m_aContext.getLegacyServiceFactory(), pElementContent, m_bTables );
+ return new OCommandDefinition( *this, _rName, m_aContext.getLegacyServiceFactory(), pElementContent );
+}
+
+Reference< XInterface > SAL_CALL OCommandContainer::createInstanceWithArguments(const Sequence< Any >& /*aArguments*/ ) throw (Exception, RuntimeException)
+{
+ return createInstance( );
+}
+
+Reference< XInterface > SAL_CALL OCommandContainer::createInstance( ) throw (Exception, RuntimeException)
+{
+ return m_aContext.createComponent( (::rtl::OUString)( m_bTables ? SERVICE_SDB_TABLEDEFINITION : SERVICE_SDB_COMMAND_DEFINITION ) );
+}
+
+::rtl::OUString OCommandContainer::determineContentType() const
+{
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/vnd.org.openoffice.DatabaseCommandDefinitionContainer" ) );
+}
+
+} // namespace dbaccess
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/commandcontainer.hxx b/dbaccess/source/core/dataaccess/commandcontainer.hxx
new file mode 100644
index 000000000000..a425d7795dbe
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/commandcontainer.hxx
@@ -0,0 +1,85 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _DBA_COREDATAACCESS_COMMANDCONTAINER_HXX_
+#define _DBA_COREDATAACCESS_COMMANDCONTAINER_HXX_
+
+#include "definitioncontainer.hxx"
+
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+
+#include <cppuhelper/implbase1.hxx>
+
+namespace dbaccess
+{
+//==========================================================================
+//= OCommandContainer
+//==========================================================================
+
+typedef ::cppu::ImplHelper1 < ::com::sun::star::lang::XSingleServiceFactory
+ > OCommandContainer_BASE;
+
+class OCommandContainer : public ODefinitionContainer
+ ,public OCommandContainer_BASE
+{
+ sal_Bool m_bTables;
+
+public:
+ /** constructs the container.<BR>
+ */
+ OCommandContainer(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _xORB
+ ,const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _xParentContainer
+ ,const TContentPtr& _pImpl
+ ,sal_Bool _bTables
+ );
+
+ DECLARE_XINTERFACE( )
+ DECLARE_TYPEPROVIDER( );
+
+ // XSingleServiceFactory
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL createInstance( ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL createInstanceWithArguments( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+
+protected:
+ virtual ~OCommandContainer();
+
+ // ODefinitionContainer
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContent > createObject(const ::rtl::OUString& _rName);
+
+protected:
+ // OContentHelper overridables
+ virtual ::rtl::OUString determineContentType() const;
+};
+
+} // namespace dbaccess
+
+
+#endif // _DBA_COREDATAACCESS_COMMANDCONTAINER_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/commanddefinition.cxx b/dbaccess/source/core/dataaccess/commanddefinition.cxx
new file mode 100644
index 000000000000..6cfd9231560f
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/commanddefinition.cxx
@@ -0,0 +1,167 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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"
+
+#include "commanddefinition.hxx"
+#include "apitools.hxx"
+#include "dbastrings.hrc"
+#include "module_dba.hxx"
+
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+
+#include <tools/debug.hxx>
+#include <comphelper/sequence.hxx>
+#include <comphelper/componentcontext.hxx>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::osl;
+using namespace ::comphelper;
+using namespace ::cppu;
+
+namespace dbaccess
+{
+
+//==========================================================================
+//= OCommandDefinition
+//==========================================================================
+extern "C" void SAL_CALL createRegistryInfo_OCommandDefinition()
+{
+ static ::dba::OAutoRegistration< OCommandDefinition > aAutoRegistration;
+}
+
+DBG_NAME(OCommandDefinition)
+
+void OCommandDefinition::registerProperties()
+{
+ OCommandDefinition_Impl& rCommandDefinition( getCommandDefinition() );
+ registerProperty(PROPERTY_COMMAND, PROPERTY_ID_COMMAND, PropertyAttribute::BOUND,
+ &rCommandDefinition.m_sCommand, ::getCppuType(&rCommandDefinition.m_sCommand));
+
+ registerProperty(PROPERTY_ESCAPE_PROCESSING, PROPERTY_ID_ESCAPE_PROCESSING, PropertyAttribute::BOUND,
+ &rCommandDefinition.m_bEscapeProcessing, ::getBooleanCppuType());
+
+ registerProperty(PROPERTY_UPDATE_TABLENAME, PROPERTY_ID_UPDATE_TABLENAME, PropertyAttribute::BOUND,
+ &rCommandDefinition.m_sUpdateTableName, ::getCppuType(&rCommandDefinition.m_sUpdateTableName));
+
+ registerProperty(PROPERTY_UPDATE_SCHEMANAME, PROPERTY_ID_UPDATE_SCHEMANAME, PropertyAttribute::BOUND,
+ &rCommandDefinition.m_sUpdateSchemaName, ::getCppuType(&rCommandDefinition.m_sUpdateSchemaName));
+
+ registerProperty(PROPERTY_UPDATE_CATALOGNAME, PROPERTY_ID_UPDATE_CATALOGNAME, PropertyAttribute::BOUND,
+ &rCommandDefinition.m_sUpdateCatalogName, ::getCppuType(&rCommandDefinition.m_sUpdateCatalogName));
+ registerProperty(PROPERTY_LAYOUTINFORMATION, PROPERTY_ID_LAYOUTINFORMATION, PropertyAttribute::BOUND,
+ &rCommandDefinition.m_aLayoutInformation, ::getCppuType(&rCommandDefinition.m_aLayoutInformation));
+}
+
+OCommandDefinition::OCommandDefinition(const Reference< XMultiServiceFactory >& _xORB
+ ,const Reference< XInterface >& _rxContainer
+ ,const TContentPtr& _pImpl)
+ :OComponentDefinition(_xORB,_rxContainer,_pImpl,sal_False)
+{
+ DBG_CTOR(OCommandDefinition, NULL);
+ registerProperties();
+}
+
+OCommandDefinition::~OCommandDefinition()
+{
+ DBG_DTOR(OCommandDefinition, NULL);
+}
+
+OCommandDefinition::OCommandDefinition( const Reference< XInterface >& _rxContainer
+ ,const ::rtl::OUString& _rElementName
+ ,const Reference< XMultiServiceFactory >& _xORB
+ ,const TContentPtr& _pImpl)
+ :OComponentDefinition(_rxContainer,_rElementName,_xORB,_pImpl,sal_False)
+{
+ DBG_CTOR(OCommandDefinition, NULL);
+ registerProperties();
+}
+
+IMPLEMENT_IMPLEMENTATION_ID(OCommandDefinition);
+IMPLEMENT_GETTYPES2(OCommandDefinition,OCommandDefinition_Base,OComponentDefinition);
+IMPLEMENT_FORWARD_XINTERFACE2( OCommandDefinition,OComponentDefinition,OCommandDefinition_Base)
+IMPLEMENT_PROPERTYCONTAINER_DEFAULTS2(OCommandDefinition,OCommandDefinition_PROP)
+
+::rtl::OUString OCommandDefinition::getImplementationName_static( ) throw(RuntimeException)
+{
+ return ::rtl::OUString::createFromAscii("com.sun.star.comp.dba.OCommandDefinition");
+}
+
+::rtl::OUString SAL_CALL OCommandDefinition::getImplementationName( ) throw(RuntimeException)
+{
+ return getImplementationName_static();
+}
+
+Sequence< ::rtl::OUString > OCommandDefinition::getSupportedServiceNames_static( ) throw(RuntimeException)
+{
+ Sequence< ::rtl::OUString > aServices(3);
+ aServices.getArray()[0] = SERVICE_SDB_QUERYDEFINITION;
+ aServices.getArray()[1] = SERVICE_SDB_COMMAND_DEFINITION;
+ aServices.getArray()[2] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.ucb.Content"));
+ return aServices;
+}
+
+Sequence< ::rtl::OUString > SAL_CALL OCommandDefinition::getSupportedServiceNames( ) throw(RuntimeException)
+{
+ return getSupportedServiceNames_static();
+}
+
+Reference< XInterface > OCommandDefinition::Create(const Reference< XComponentContext >& _rxContext)
+{
+ ::comphelper::ComponentContext aContext( _rxContext );
+ return *(new OCommandDefinition( aContext.getLegacyServiceFactory(), NULL, TContentPtr( new OCommandDefinition_Impl ) ) );
+}
+
+void SAL_CALL OCommandDefinition::rename( const ::rtl::OUString& newName ) throw (SQLException, ElementExistException, RuntimeException)
+{
+ try
+ {
+ sal_Int32 nHandle = PROPERTY_ID_NAME;
+ osl::ClearableGuard< osl::Mutex > aGuard(m_aMutex);
+ Any aOld = makeAny(m_pImpl->m_aProps.aTitle);
+ aGuard.clear();
+ Any aNew = makeAny(newName);
+ fire(&nHandle, &aNew, &aOld, 1, sal_True );
+
+ m_pImpl->m_aProps.aTitle = newName;
+ fire(&nHandle, &aNew, &aOld, 1, sal_False );
+ }
+ catch(const PropertyVetoException&)
+ {
+ throw ElementExistException(newName,*this);
+ }
+}
+
+} // namespace dbaccess
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/commanddefinition.hxx b/dbaccess/source/core/dataaccess/commanddefinition.hxx
new file mode 100644
index 000000000000..b823c08f86d2
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/commanddefinition.hxx
@@ -0,0 +1,123 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _DBA_COREDATAACESS_COMMANDDEFINITION_HXX_
+#define _DBA_COREDATAACESS_COMMANDDEFINITION_HXX_
+
+#include "commandbase.hxx"
+#include <comphelper/propertycontainer.hxx>
+#include "apitools.hxx"
+#include <comphelper/uno3.hxx>
+#include <com/sun/star/sdbcx/XRename.hpp>
+#include <cppuhelper/implbase1.hxx>
+#include <comphelper/proparrhlp.hxx>
+#include "datasettings.hxx"
+#include <com/sun/star/container/XNameAccess.hpp>
+#include "ContentHelper.hxx"
+#include "ComponentDefinition.hxx"
+
+
+//........................................................................
+namespace dbaccess
+{
+//........................................................................
+
+//=========================================================================
+//= OCommandDefinition - a database "document" which describes a query
+//=========================================================================
+ class OCommandDefinition_Impl : public OComponentDefinition_Impl
+ ,public OCommandBase
+ {
+ public:
+ };
+
+typedef ::cppu::ImplHelper1 < ::com::sun::star::sdbcx::XRename
+ > OCommandDefinition_Base;
+class OCommandDefinition;
+typedef ::comphelper::OPropertyArrayUsageHelper< OCommandDefinition >
+ OCommandDefinition_PROP;
+
+class OCommandDefinition :public OComponentDefinition
+ ,public OCommandDefinition_Base
+ ,public OCommandDefinition_PROP
+{
+protected:
+ virtual ~OCommandDefinition();
+
+ OCommandDefinition(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&
+ ,const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _xParentContainer
+ ,const TContentPtr& _pImpl
+ );
+
+ inline const OCommandDefinition_Impl& getCommandDefinition() const { return dynamic_cast< const OCommandDefinition_Impl& >( *m_pImpl.get() ); }
+ inline OCommandDefinition_Impl& getCommandDefinition() { return dynamic_cast< OCommandDefinition_Impl& >( *m_pImpl.get() ); }
+
+public:
+
+ OCommandDefinition(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxContainer
+ ,const ::rtl::OUString& _rElementName
+ ,const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&
+ ,const TContentPtr& _pImpl
+ );
+
+// com::sun::star::lang::XTypeProvider
+ DECLARE_TYPEPROVIDER( );
+
+// ::com::sun::star::uno::XInterface
+ DECLARE_XINTERFACE( )
+
+// ::com::sun::star::lang::XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException);
+
+// ::com::sun::star::lang::XServiceInfo - static methods
+ static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_static(void) throw( ::com::sun::star::uno::RuntimeException );
+ static ::rtl::OUString getImplementationName_static(void) throw( ::com::sun::star::uno::RuntimeException );
+ static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL
+ Create(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >&);
+
+ // XRename
+ virtual void SAL_CALL rename( const ::rtl::OUString& newName ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException);
+
+ // OPropertySetHelper
+ DECLARE_PROPERTYCONTAINER_DEFAULTS( );
+
+private:
+ // helper
+ void registerProperties();
+};
+
+//........................................................................
+} // namespace dbaccess
+//........................................................................
+
+#endif // _DBA_COREDATAACESS_COMMANDDEFINITION_HXX_
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/connection.cxx b/dbaccess/source/core/dataaccess/connection.cxx
new file mode 100644
index 000000000000..490d0c47ffe0
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/connection.cxx
@@ -0,0 +1,894 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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"
+
+#include "connection.hxx"
+#include "dbastrings.hrc"
+#include "datasource.hxx"
+#include "core_resource.hrc"
+#include "core_resource.hxx"
+#include "statement.hxx"
+#include "preparedstatement.hxx"
+#include "callablestatement.hxx"
+#include "ContainerMediator.hxx"
+#include "SingleSelectQueryComposer.hxx"
+#include "querycomposer.hxx"
+#include "sdbcoretools.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/sdb/CommandType.hpp>
+#include <com/sun/star/sdbc/XDriverAccess.hpp>
+#include <com/sun/star/sdbcx/XDataDefinitionSupplier.hpp>
+#include <com/sun/star/reflection/XProxyFactory.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+/** === end UNO includes === **/
+#include <connectivity/dbtools.hxx>
+#include <connectivity/dbmetadata.hxx>
+#include <connectivity/dbexception.hxx>
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+#include <comphelper/extract.hxx>
+#include <comphelper/uno3.hxx>
+#include <comphelper/sequence.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <rtl/logfile.hxx>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::sdb::application;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::reflection;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::graphic;
+using namespace ::osl;
+using namespace ::comphelper;
+using namespace ::cppu;
+using namespace ::dbtools;
+
+using ::com::sun::star::sdb::tools::XTableName;
+using ::com::sun::star::sdb::tools::XObjectNames;
+using ::com::sun::star::sdb::tools::XDataSourceMetaData;
+
+namespace dbaccess
+{
+
+//==========================================================================
+// XServiceInfo
+rtl::OUString OConnection::getImplementationName( ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getImplementationName" );
+ return rtl::OUString::createFromAscii("com.sun.star.comp.dbaccess.Connection");
+}
+
+sal_Bool OConnection::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::supportsService" );
+ return findValue(getSupportedServiceNames(), _rServiceName, sal_True).getLength() != 0;
+}
+
+Sequence< ::rtl::OUString > OConnection::getSupportedServiceNames( ) throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getSupportedServiceNames" );
+ Sequence< ::rtl::OUString > aSupported = OConnectionWrapper::getSupportedServiceNames();
+
+ if ( 0 == findValue( aSupported, SERVICE_SDB_CONNECTION, sal_True ).getLength() )
+ {
+ sal_Int32 nLen = aSupported.getLength();
+ aSupported.realloc( nLen + 1 );
+ aSupported[ nLen ] = SERVICE_SDB_CONNECTION;
+ }
+
+ return aSupported;
+}
+
+// XCloseable
+void OConnection::close(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::close" );
+ // being closed is the same as being disposed
+ dispose();
+}
+
+sal_Bool OConnection::isClosed(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::isClosed" );
+ MutexGuard aGuard(m_aMutex);
+ return !m_xMasterConnection.is();
+}
+
+// XConnection
+Reference< XStatement > OConnection::createStatement(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::createStatement" );
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed();
+
+ Reference< XStatement > xStatement;
+ Reference< XStatement > xMasterStatement = m_xMasterConnection->createStatement();
+ if ( xMasterStatement.is() )
+ {
+ xStatement = new OStatement(this, xMasterStatement);
+ m_aStatements.push_back(WeakReferenceHelper(xStatement));
+ }
+ return xStatement;
+}
+Reference< XPreparedStatement > OConnection::prepareStatement(const rtl::OUString& sql) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::prepareStatement" );
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed();
+
+ // TODO convert the SQL to SQL the driver understands
+ Reference< XPreparedStatement > xStatement;
+ Reference< XPreparedStatement > xMasterStatement = m_xMasterConnection->prepareStatement(sql);
+ if ( xMasterStatement.is() )
+ {
+ xStatement = new OPreparedStatement(this, xMasterStatement);
+ m_aStatements.push_back(WeakReferenceHelper(xStatement));
+ }
+ return xStatement;
+}
+
+Reference< XPreparedStatement > OConnection::prepareCall(const rtl::OUString& sql) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::prepareCall" );
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed();
+
+ Reference< XPreparedStatement > xStatement;
+ Reference< XPreparedStatement > xMasterStatement = m_xMasterConnection->prepareCall(sql);
+ if ( xMasterStatement.is() )
+ {
+ xStatement = new OCallableStatement(this, xMasterStatement);
+ m_aStatements.push_back(WeakReferenceHelper(xStatement));
+ }
+ return xStatement;
+}
+
+rtl::OUString OConnection::nativeSQL(const rtl::OUString& sql) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::nativeSQL" );
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed();
+ return m_xMasterConnection->nativeSQL(sql);
+}
+
+void OConnection::setAutoCommit(sal_Bool autoCommit) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::setAutoCommit" );
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed();
+ m_xMasterConnection->setAutoCommit(autoCommit);
+}
+
+sal_Bool OConnection::getAutoCommit(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getAutoCommit" );
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed();
+ return m_xMasterConnection->getAutoCommit();
+}
+
+void OConnection::commit(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::commit" );
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed();
+ m_xMasterConnection->commit();
+}
+
+void OConnection::rollback(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::rollback" );
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed();
+ m_xMasterConnection->rollback();
+}
+
+Reference< XDatabaseMetaData > OConnection::getMetaData(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getMetaData" );
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed();
+ return m_xMasterConnection->getMetaData();
+}
+
+void OConnection::setReadOnly(sal_Bool readOnly) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::setReadOnly" );
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed();
+ m_xMasterConnection->setReadOnly(readOnly);
+}
+
+sal_Bool OConnection::isReadOnly(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::isReadOnly" );
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed();
+ return m_xMasterConnection->isReadOnly();
+}
+
+void OConnection::setCatalog(const rtl::OUString& catalog) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::setCatalog" );
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed();
+ m_xMasterConnection->setCatalog(catalog);
+}
+
+rtl::OUString OConnection::getCatalog(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getCatalog" );
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed();
+ return m_xMasterConnection->getCatalog();
+}
+
+void OConnection::setTransactionIsolation(sal_Int32 level) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::setTransactionIsolation" );
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed();
+ m_xMasterConnection->setTransactionIsolation(level);
+}
+
+sal_Int32 OConnection::getTransactionIsolation(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getTransactionIsolation" );
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed();
+ return m_xMasterConnection->getTransactionIsolation();
+}
+
+Reference< XNameAccess > OConnection::getTypeMap(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getTypeMap" );
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed();
+ return m_xMasterConnection->getTypeMap();
+}
+
+void OConnection::setTypeMap(const Reference< XNameAccess > & typeMap) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::setTypeMap" );
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed();
+ m_xMasterConnection->setTypeMap(typeMap);
+}
+//==========================================================================
+//= OConnection
+//==========================================================================
+DBG_NAME(OConnection)
+
+OConnection::OConnection(ODatabaseSource& _rDB
+ , Reference< XConnection >& _rxMaster
+ , const Reference< XMultiServiceFactory >& _rxORB)
+ :OSubComponent(m_aMutex, static_cast< OWeakObject* >(&_rDB))
+ // as the queries reroute their refcounting to us, this m_aMutex is okey. If the queries
+ // container would do it's own refcounting, it would have to aquire m_pMutex
+ // same for tables
+ ,m_aTableFilter(_rDB.m_pImpl->m_aTableFilter)
+ ,m_aTableTypeFilter(_rDB.m_pImpl->m_aTableTypeFilter)
+ ,m_aContext( _rxORB )
+ ,m_xMasterConnection(_rxMaster)
+ ,m_pTables(NULL)
+ ,m_pViews(NULL)
+ ,m_aWarnings( Reference< XWarningsSupplier >( _rxMaster, UNO_QUERY ) )
+ ,m_nInAppend(0)
+ ,m_bSupportsViews(sal_False)
+ ,m_bSupportsUsers(sal_False)
+ ,m_bSupportsGroups(sal_False)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::OConnection" );
+ DBG_CTOR(OConnection,NULL);
+ osl_incrementInterlockedCount(&m_refCount);
+
+ try
+ {
+ Reference< XProxyFactory > xProxyFactory(
+ _rxORB->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.reflection.ProxyFactory"))),UNO_QUERY);
+ Reference<XAggregation> xAgg = xProxyFactory->createProxy(_rxMaster.get());
+ setDelegation(xAgg,m_refCount);
+ DBG_ASSERT(m_xConnection.is(), "OConnection::OConnection : invalid master connection !");
+ }
+ catch(const Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ m_xTableUIProvider = m_xTableUIProvider.query( m_xMasterConnection );
+
+ try
+ {
+ m_xQueries = new OQueryContainer(Reference< XNameContainer >(_rDB.getQueryDefinitions( ),UNO_QUERY), this,_rxORB, &m_aWarnings);
+
+ sal_Bool bCase = sal_True;
+ Reference<XDatabaseMetaData> xMeta;
+ try
+ {
+ xMeta = getMetaData();
+ bCase = xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers();
+ }
+ catch(SQLException&)
+ {
+ }
+ Reference< XNameContainer > xTableDefinitions(_rDB.getTables(),UNO_QUERY);
+ m_pTables = new OTableContainer( *this, m_aMutex, this, bCase, xTableDefinitions, this, &m_aWarnings,m_nInAppend );
+
+ // check if we supports types
+ if ( xMeta.is() )
+ {
+ Reference<XResultSet> xRes = xMeta->getTableTypes();
+ if(xRes.is())
+ {
+ ::rtl::OUString sView(RTL_CONSTASCII_USTRINGPARAM("VIEW"));
+ Reference<XRow> xRow(xRes,UNO_QUERY);
+ while(xRes->next())
+ {
+ ::rtl::OUString sValue = xRow->getString(1);
+ if( !xRow->wasNull() && sValue == sView)
+ {
+ m_bSupportsViews = sal_True;
+ break;
+ }
+ }
+ }
+ // some dbs don't support this type so we should ask if a XViewsSupplier is supported
+ if(!m_bSupportsViews)
+ {
+ Reference< XViewsSupplier > xMaster(getMasterTables(),UNO_QUERY);
+
+ if (xMaster.is() && xMaster->getViews().is())
+ m_bSupportsViews = sal_True;
+ }
+ if(m_bSupportsViews)
+ {
+ m_pViews = new OViewContainer(*this, m_aMutex, this, bCase,this,&m_aWarnings,m_nInAppend);
+ m_pViews->addContainerListener(m_pTables);
+ m_pTables->addContainerListener(m_pViews);
+ }
+ m_bSupportsUsers = Reference< XUsersSupplier> (getMasterTables(),UNO_QUERY).is();
+ m_bSupportsGroups = Reference< XGroupsSupplier> (getMasterTables(),UNO_QUERY).is();
+
+ impl_checkTableQueryNames_nothrow();
+ }
+ }
+ catch(const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ osl_decrementInterlockedCount( &m_refCount );
+}
+
+OConnection::~OConnection()
+{
+ delete m_pTables;
+ delete m_pViews;
+ DBG_DTOR(OConnection,NULL);
+}
+
+// XWarningsSupplier
+Any SAL_CALL OConnection::getWarnings() throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getWarnings" );
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed();
+ return m_aWarnings.getWarnings();
+}
+
+void SAL_CALL OConnection::clearWarnings( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::clearWarnings" );
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed();
+ m_aWarnings.clearWarnings();
+}
+
+namespace
+{
+ struct CompareTypeByName : public ::std::binary_function< Type, Type, bool >
+ {
+ bool operator() ( const Type& _rLHS, const Type& _rRHS ) const
+ {
+ return _rLHS.getTypeName() < _rRHS.getTypeName();
+ }
+ };
+ typedef ::std::set< Type, CompareTypeByName > TypeBag;
+
+ void lcl_copyTypes( TypeBag& _out_rTypes, const Sequence< Type >& _rTypes )
+ {
+ ::std::copy( _rTypes.getConstArray(), _rTypes.getConstArray() + _rTypes.getLength(),
+ ::std::insert_iterator< TypeBag >( _out_rTypes, _out_rTypes.begin() ) );
+ }
+}
+
+// com::sun::star::lang::XTypeProvider
+Sequence< Type > OConnection::getTypes() throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getTypes" );
+ TypeBag aNormalizedTypes;
+
+ lcl_copyTypes( aNormalizedTypes, OSubComponent::getTypes() );
+ lcl_copyTypes( aNormalizedTypes, OConnection_Base::getTypes() );
+ lcl_copyTypes( aNormalizedTypes, ::connectivity::OConnectionWrapper::getTypes() );
+
+ if ( !m_bSupportsViews )
+ aNormalizedTypes.erase( XViewsSupplier::static_type() );
+ if ( !m_bSupportsUsers )
+ aNormalizedTypes.erase( XUsersSupplier::static_type() );
+ if ( !m_bSupportsGroups )
+ aNormalizedTypes.erase( XGroupsSupplier::static_type() );
+
+ Sequence< Type > aSupportedTypes( aNormalizedTypes.size() );
+ ::std::copy( aNormalizedTypes.begin(), aNormalizedTypes.end(), aSupportedTypes.getArray() );
+ return aSupportedTypes;
+}
+
+Sequence< sal_Int8 > OConnection::getImplementationId() throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getImplementationId" );
+ return getUnoTunnelImplementationId();
+}
+
+// com::sun::star::uno::XInterface
+Any OConnection::queryInterface( const Type & rType ) throw (RuntimeException)
+{
+ if ( !m_bSupportsViews && rType.equals( XViewsSupplier::static_type() ) )
+ return Any();
+ else if ( !m_bSupportsUsers && rType.equals( XUsersSupplier::static_type() ) )
+ return Any();
+ else if ( !m_bSupportsGroups && rType.equals( XGroupsSupplier::static_type() ) )
+ return Any();
+ Any aReturn = OSubComponent::queryInterface( rType );
+ if (!aReturn.hasValue())
+ {
+ aReturn = OConnection_Base::queryInterface( rType );
+ if (!aReturn.hasValue())
+ aReturn = OConnectionWrapper::queryInterface( rType );
+ }
+ return aReturn;
+}
+
+void OConnection::acquire() throw ()
+{
+ // include this one when you want to see who calls it (call graph)
+ OSubComponent::acquire();
+}
+
+void OConnection::release() throw ()
+{
+ // include this one when you want to see who calls it (call graph)
+ OSubComponent::release();
+}
+
+// OSubComponent
+void OConnection::disposing()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::disposing" );
+ MutexGuard aGuard(m_aMutex);
+
+ OSubComponent::disposing();
+ OConnectionWrapper::disposing();
+
+ OWeakRefArrayIterator aEnd = m_aStatements.end();
+ for (OWeakRefArrayIterator i = m_aStatements.begin(); aEnd != i; ++i)
+ {
+ Reference<XComponent> xComp(i->get(),UNO_QUERY);
+ ::comphelper::disposeComponent(xComp);
+ }
+ m_aStatements.clear();
+ m_xMasterTables = NULL;
+
+ if(m_pTables)
+ m_pTables->dispose();
+ if(m_pViews)
+ m_pViews->dispose();
+
+ ::comphelper::disposeComponent(m_xQueries);
+
+ OWeakRefArrayIterator aComposerEnd = m_aComposers.end();
+ for (OWeakRefArrayIterator j = m_aComposers.begin(); aComposerEnd != j; ++j)
+ {
+ Reference<XComponent> xComp(j->get(),UNO_QUERY);
+ ::comphelper::disposeComponent(xComp);
+ }
+
+ m_aComposers.clear();
+
+ try
+ {
+ if (m_xMasterConnection.is())
+ m_xMasterConnection->close();
+ }
+ catch(Exception)
+ {
+ }
+ m_xMasterConnection = NULL;
+}
+
+// XChild
+Reference< XInterface > OConnection::getParent(void) throw( RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getParent" );
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed();
+ return m_xParent;
+}
+
+void OConnection::setParent(const Reference< XInterface > & /*Parent*/) throw( NoSupportException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::setParent" );
+ throw NoSupportException();
+}
+
+// XSQLQueryComposerFactory
+Reference< XSQLQueryComposer > OConnection::createQueryComposer(void) throw( RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::createQueryComposer" );
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed();
+
+ // Reference< XNumberFormatsSupplier > xSupplier = pParent->getNumberFormatsSupplier();
+ Reference< XSQLQueryComposer > xComposer( new OQueryComposer( this ) );
+ m_aComposers.push_back(WeakReferenceHelper(xComposer));
+ return xComposer;
+}
+
+void OConnection::impl_fillTableFilter()
+{
+ Reference<XPropertySet> xProp(getParent(),UNO_QUERY);
+ if ( xProp.is() )
+ {
+ xProp->getPropertyValue(PROPERTY_TABLEFILTER) >>= m_aTableFilter;
+ xProp->getPropertyValue(PROPERTY_TABLETYPEFILTER) >>= m_aTableTypeFilter;
+ }
+}
+
+void OConnection::refresh(const Reference< XNameAccess >& _rToBeRefreshed)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::refresh" );
+ if ( _rToBeRefreshed == Reference< XNameAccess >(m_pTables) )
+ {
+ if (m_pTables && !m_pTables->isInitialized())
+ {
+ impl_fillTableFilter();
+ // check if our "master connection" can supply tables
+ getMasterTables();
+
+ if (m_xMasterTables.is() && m_xMasterTables->getTables().is())
+ { // yes -> wrap them
+ m_pTables->construct(m_xMasterTables->getTables(),m_aTableFilter, m_aTableTypeFilter);
+ }
+ else
+ { // no -> use an own container
+ m_pTables->construct(m_aTableFilter, m_aTableTypeFilter);
+ }
+ }
+ }
+ else if ( _rToBeRefreshed == Reference< XNameAccess >(m_pViews) )
+ {
+ if (m_pViews && !m_pViews->isInitialized())
+ {
+ impl_fillTableFilter();
+ // check if our "master connection" can supply tables
+ Reference< XViewsSupplier > xMaster(getMasterTables(),UNO_QUERY);
+
+ if (xMaster.is() && xMaster->getViews().is())
+ m_pViews->construct(xMaster->getViews(),m_aTableFilter, m_aTableTypeFilter);
+ else
+ m_pViews->construct(m_aTableFilter, m_aTableTypeFilter);
+ }
+ }
+}
+
+// XTablesSupplier
+Reference< XNameAccess > OConnection::getTables() throw( RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getTables" );
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed();
+
+ refresh(m_pTables);
+
+ return m_pTables;
+}
+
+Reference< XNameAccess > SAL_CALL OConnection::getViews( ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getViews" );
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed();
+
+ refresh(m_pViews);
+
+ return m_pViews;
+}
+// XQueriesSupplier
+Reference< XNameAccess > OConnection::getQueries(void) throw( RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getQueries" );
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed();
+
+ return m_xQueries;
+}
+
+// ::com::sun::star::sdb::XCommandPreparation
+Reference< XPreparedStatement > SAL_CALL OConnection::prepareCommand( const ::rtl::OUString& command, sal_Int32 commandType ) throw(::com::sun::star::sdbc::SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::prepareCommand" );
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed();
+
+ rtl::OUString aStatement;
+ switch (commandType)
+ {
+ case CommandType::TABLE:
+ {
+ aStatement = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SELECT * FROM "));
+
+ ::rtl::OUString sCatalog, sSchema, sTable;
+ ::dbtools::qualifiedNameComponents( getMetaData(), command, sCatalog, sSchema, sTable, ::dbtools::eInDataManipulation );
+ aStatement += ::dbtools::composeTableNameForSelect( this, sCatalog, sSchema, sTable );
+ }
+ break;
+ case CommandType::QUERY:
+ if ( m_xQueries->hasByName(command) )
+ {
+ Reference< XPropertySet > xQuery(m_xQueries->getByName(command),UNO_QUERY);
+ xQuery->getPropertyValue(PROPERTY_COMMAND) >>= aStatement;
+ }
+ break;
+ default:
+ aStatement = command;
+ }
+ // TODO EscapeProcessing
+ return prepareStatement(aStatement);
+}
+
+Reference< XInterface > SAL_CALL OConnection::createInstance( const ::rtl::OUString& _sServiceSpecifier ) throw (Exception, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::createInstance" );
+ Reference< XServiceInfo > xRet;
+ if ( ( SERVICE_NAME_SINGLESELECTQUERYCOMPOSER == _sServiceSpecifier )
+ || ( _sServiceSpecifier.equalsAscii( "com.sun.star.sdb.SingleSelectQueryAnalyzer" ) )
+ )
+ {
+ xRet = new OSingleSelectQueryComposer( getTables(),this, m_aContext );
+ m_aComposers.push_back(WeakReferenceHelper(xRet));
+ }
+ else
+ {
+ if ( _sServiceSpecifier.getLength() )
+ {
+ TSupportServices::iterator aFind = m_aSupportServices.find(_sServiceSpecifier);
+ if ( aFind == m_aSupportServices.end() )
+ {
+ Sequence<Any> aArgs(1);
+ Reference<XConnection> xMy(this);
+ aArgs[0] <<= NamedValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ActiveConnection")),makeAny(xMy));
+ aFind = m_aSupportServices.insert(TSupportServices::value_type(_sServiceSpecifier,m_aContext.createComponentWithArguments(_sServiceSpecifier,aArgs))).first;
+ }
+ return aFind->second;
+ }
+ }
+ return Reference< XInterface >(xRet,UNO_QUERY);
+}
+
+Reference< XInterface > SAL_CALL OConnection::createInstanceWithArguments( const ::rtl::OUString& _sServiceSpecifier, const Sequence< Any >& /*Arguments*/ ) throw (Exception, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::createInstanceWithArguments" );
+ return createInstance(_sServiceSpecifier);
+}
+
+Sequence< ::rtl::OUString > SAL_CALL OConnection::getAvailableServiceNames( ) throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getAvailableServiceNames" );
+ Sequence< ::rtl::OUString > aRet(1);
+ aRet[0] = SERVICE_NAME_SINGLESELECTQUERYCOMPOSER;
+ return aRet;
+}
+
+Reference< XTablesSupplier > OConnection::getMasterTables()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getMasterTables" );
+// check if out "master connection" can supply tables
+ if(!m_xMasterTables.is())
+ {
+ try
+ {
+ Reference<XDatabaseMetaData> xMeta = getMetaData();
+ if ( xMeta.is() )
+ m_xMasterTables = ::dbtools::getDataDefinitionByURLAndConnection( xMeta->getURL(), m_xMasterConnection, m_aContext.getLegacyServiceFactory() );
+ }
+ catch(SQLException&)
+ {
+ }
+ }
+ return m_xMasterTables;
+}
+
+// XUsersSupplier
+Reference< XNameAccess > SAL_CALL OConnection::getUsers( ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getUsers" );
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed();
+
+ Reference<XUsersSupplier> xUsr(getMasterTables(),UNO_QUERY);
+ return xUsr.is() ? xUsr->getUsers() : Reference< XNameAccess >();
+}
+
+// XGroupsSupplier
+Reference< XNameAccess > SAL_CALL OConnection::getGroups( ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getGroups" );
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed();
+ Reference<XGroupsSupplier> xGrp(getMasterTables(),UNO_QUERY);
+ return xGrp.is() ? xGrp->getGroups() : Reference< XNameAccess >();
+}
+
+void OConnection::impl_loadConnectionTools_throw()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::impl_loadConnectionTools_throw" );
+ Sequence< Any > aArguments( 1 );
+ aArguments[0] <<= NamedValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Connection" ) ), makeAny( Reference< XConnection >( this ) ) );
+
+ if ( !m_aContext.createComponentWithArguments( "com.sun.star.sdb.tools.ConnectionTools", aArguments, m_xConnectionTools ) )
+ throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "service not registered: com.sun.star.sdb.tools.ConnectionTools" ) ), *this );
+}
+
+Reference< XTableName > SAL_CALL OConnection::createTableName( ) throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::createTableName" );
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed();
+ impl_loadConnectionTools_throw();
+
+ return m_xConnectionTools->createTableName();
+}
+
+Reference< XObjectNames > SAL_CALL OConnection::getObjectNames( ) throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getObjectNames" );
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed();
+ impl_loadConnectionTools_throw();
+
+ return m_xConnectionTools->getObjectNames();
+}
+
+Reference< XDataSourceMetaData > SAL_CALL OConnection::getDataSourceMetaData( ) throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getDataSourceMetaData" );
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed();
+ impl_loadConnectionTools_throw();
+
+ return m_xConnectionTools->getDataSourceMetaData();
+}
+
+Reference< ::com::sun::star::container::XNameAccess > SAL_CALL OConnection::getFieldsByCommandDescriptor( ::sal_Int32 commandType, const ::rtl::OUString& command, ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& keepFieldsAlive ) throw (::com::sun::star::sdbc::SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getFieldsByCommandDescriptor" );
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed();
+ impl_loadConnectionTools_throw();
+
+ return m_xConnectionTools->getFieldsByCommandDescriptor(commandType,command,keepFieldsAlive);
+}
+
+Reference< XSingleSelectQueryComposer > SAL_CALL OConnection::getComposer( ::sal_Int32 commandType, const ::rtl::OUString& command ) throw (::com::sun::star::uno::RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getComposer" );
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed();
+ impl_loadConnectionTools_throw();
+
+ return m_xConnectionTools->getComposer(commandType,command);
+}
+
+void OConnection::impl_checkTableQueryNames_nothrow()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::impl_checkTableQueryNames_nothrow" );
+ DatabaseMetaData aMeta( static_cast< XConnection* >( this ) );
+ if ( !aMeta.supportsSubqueriesInFrom() )
+ // nothing to do
+ return;
+
+ try
+ {
+ Reference< XNameAccess > xTables( getTables() );
+ Sequence< ::rtl::OUString > aTableNames( xTables->getElementNames() );
+ ::std::set< ::rtl::OUString > aSortedTableNames( aTableNames.getConstArray(), aTableNames.getConstArray() + aTableNames.getLength() );
+
+ Reference< XNameAccess > xQueries( getQueries() );
+ Sequence< ::rtl::OUString > aQueryNames( xQueries->getElementNames() );
+
+ for ( const ::rtl::OUString* pQueryName = aQueryNames.getConstArray();
+ pQueryName != aQueryNames.getConstArray() + aQueryNames.getLength();
+ ++pQueryName
+ )
+ {
+ if ( aSortedTableNames.find( *pQueryName ) != aSortedTableNames.end() )
+ {
+ ::rtl::OUString sConflictWarning( DBACORE_RESSTRING( RID_STR_CONFLICTING_NAMES ) );
+ m_aWarnings.appendWarning( sConflictWarning, "01SB0", *this );
+ }
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+}
+
+Reference< XGraphic > SAL_CALL OConnection::getTableIcon( const ::rtl::OUString& _TableName, ::sal_Int32 _ColorMode ) throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getTableIcon" );
+ Reference< XGraphic > xReturn;
+
+ // ask our aggregate
+ if ( m_xTableUIProvider.is() )
+ xReturn = m_xTableUIProvider->getTableIcon( _TableName, _ColorMode );
+
+ // ask ourself
+ // well, we don't have own functionality here ...
+ // In the future, we might decide to delegate the complete handling to this interface.
+ // In this case, we would need to load the icon here.
+
+ return xReturn;
+}
+
+Reference< XInterface > SAL_CALL OConnection::getTableEditor( const Reference< XDatabaseDocumentUI >& _DocumentUI, const ::rtl::OUString& _TableName ) throw (IllegalArgumentException, WrappedTargetException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getTableEditor" );
+ Reference< XInterface > xReturn;
+
+ // ask our aggregate
+ if ( m_xTableUIProvider.is() )
+ xReturn = m_xTableUIProvider->getTableEditor( _DocumentUI, _TableName );
+
+ // ask ourself
+ // well, we don't have own functionality here ...
+ // In the future, we might decide to delegate the complete handling to this interface.
+ // In this case, we would need to instantiate an css.sdb.TableDesign here.
+
+ return xReturn;
+}
+
+} // namespace dbaccess
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/connection.hxx b/dbaccess/source/core/dataaccess/connection.hxx
new file mode 100644
index 000000000000..2918d4f74192
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/connection.hxx
@@ -0,0 +1,254 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _DBA_CORE_CONNECTION_HXX_
+#define _DBA_CORE_CONNECTION_HXX_
+
+#include "apitools.hxx"
+#include "querycontainer.hxx"
+#include "tablecontainer.hxx"
+#include "viewcontainer.hxx"
+#include "RefreshListener.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/sdb/XSQLQueryComposerFactory.hpp>
+#include <com/sun/star/sdb/XCommandPreparation.hpp>
+#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
+#include <com/sun/star/sdbcx/XViewsSupplier.hpp>
+#include <com/sun/star/sdbcx/XUsersSupplier.hpp>
+#include <com/sun/star/sdbcx/XGroupsSupplier.hpp>
+#include <com/sun/star/sdb/XQueriesSupplier.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/sdb/tools/XConnectionTools.hpp>
+#include <com/sun/star/sdb/application/XTableUIProvider.hpp>
+/** === end UNO includes === **/
+
+#if ! defined(INCLUDED_COMPHELPER_IMPLBASE_VAR_HXX_14)
+#define INCLUDED_COMPHELPER_IMPLBASE_VAR_HXX_14
+#define COMPHELPER_IMPLBASE_INTERFACE_NUMBER 14
+#include <comphelper/implbase_var.hxx>
+#endif
+#include <comphelper/componentcontext.hxx>
+#include <comphelper/stl_types.hxx>
+#include <connectivity/ConnectionWrapper.hxx>
+#include <connectivity/warningscontainer.hxx>
+
+//........................................................................
+namespace dbaccess
+{
+//........................................................................
+
+//==========================================================================
+//==========================================================================
+typedef ::comphelper::ImplHelper14 < ::com::sun::star::container::XChild
+ , ::com::sun::star::sdbcx::XTablesSupplier
+ , ::com::sun::star::sdbcx::XViewsSupplier
+ , ::com::sun::star::sdbc::XConnection
+ , ::com::sun::star::sdbc::XWarningsSupplier
+ , ::com::sun::star::sdb::XQueriesSupplier
+ , ::com::sun::star::sdb::XSQLQueryComposerFactory
+ , ::com::sun::star::sdb::XCommandPreparation
+ , ::com::sun::star::lang::XServiceInfo
+ , ::com::sun::star::lang::XMultiServiceFactory
+ , ::com::sun::star::sdbcx::XUsersSupplier
+ , ::com::sun::star::sdbcx::XGroupsSupplier
+ , ::com::sun::star::sdb::tools::XConnectionTools
+ , ::com::sun::star::sdb::application::XTableUIProvider
+ > OConnection_Base;
+
+class ODatabaseSource;
+//==========================================================================
+//= OConnection
+//==========================================================================
+class OConnection :public ::comphelper::OBaseMutex
+ ,public OSubComponent
+ ,public ::connectivity::OConnectionWrapper
+ ,public OConnection_Base
+ ,public IRefreshListener
+{
+protected:
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbcx::XTablesSupplier >
+ m_xMasterTables; // just to avoid the recreation of the catalog
+ OWeakRefArray m_aStatements;
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >
+ m_xQueries;
+ OWeakRefArray m_aComposers;
+
+ // the filter as set on the parent data link at construction of the connection
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > m_aTableFilter;
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > m_aTableTypeFilter;
+ ::comphelper::ComponentContext m_aContext;
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > m_xMasterConnection;
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdb::tools::XConnectionTools > m_xConnectionTools;
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdb::application::XTableUIProvider > m_xTableUIProvider;
+
+ // defines the helper services for example to query the command of a view
+ // @ see com.sun.star.sdb.tools.XViewAccess
+ DECLARE_STL_USTRINGACCESS_MAP( ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface>, TSupportServices);
+ TSupportServices m_aSupportServices;
+
+
+ OTableContainer* m_pTables;
+ OViewContainer* m_pViews;
+ ::dbtools::WarningsContainer m_aWarnings;
+ oslInterlockedCount m_nInAppend;
+ sal_Bool m_bSupportsViews; // true when the getTableTypes return "VIEW" as type
+ sal_Bool m_bSupportsUsers;
+ sal_Bool m_bSupportsGroups;
+
+protected:
+ virtual ~OConnection();
+public:
+ OConnection(ODatabaseSource& _rDB
+ ,::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxMaster
+ ,const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB);
+
+// com::sun::star::lang::XTypeProvider
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException);
+
+// com::sun::star::uno::XInterface
+ virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL acquire() throw( );
+ virtual void SAL_CALL release() throw( );
+
+// OComponentHelper
+ virtual void SAL_CALL disposing(void);
+
+// ::com::sun::star::container::XChild
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL getParent( ) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setParent( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& Parent ) throw(::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException);
+
+// ::com::sun::star::sdbcx::XTablesSupplier
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL getTables( ) throw(::com::sun::star::uno::RuntimeException);
+// ::com::sun::star::sdbcx::XViewsSupplier
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL getViews( ) throw(::com::sun::star::uno::RuntimeException);
+
+// ::com::sun::star::sdb::XQueriesSupplier
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL getQueries( ) throw(::com::sun::star::uno::RuntimeException);
+
+// ::com::sun::star::sdb::XSQLQueryComposerFactory
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XSQLQueryComposer > SAL_CALL createQueryComposer( ) throw(::com::sun::star::uno::RuntimeException);
+
+// ::com::sun::star::sdb::XCommandPreparation
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XPreparedStatement > SAL_CALL prepareCommand( const ::rtl::OUString& command, sal_Int32 commandType ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+
+// ::com::sun::star::sdbc::XWarningsSupplier
+ virtual ::com::sun::star::uno::Any SAL_CALL getWarnings( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL clearWarnings( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+
+// ::com::sun::star::lang::XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException);
+
+// XConnection
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XStatement > SAL_CALL createStatement( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XPreparedStatement > SAL_CALL prepareStatement( const ::rtl::OUString& sql ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XPreparedStatement > SAL_CALL prepareCall( const ::rtl::OUString& sql ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL nativeSQL( const ::rtl::OUString& sql ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setAutoCommit( sal_Bool autoCommit ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL getAutoCommit( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL commit( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL rollback( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL isClosed( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData > SAL_CALL getMetaData( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setReadOnly( sal_Bool readOnly ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL isReadOnly( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setCatalog( const ::rtl::OUString& catalog ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getCatalog( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setTransactionIsolation( sal_Int32 level ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getTransactionIsolation( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL getTypeMap( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setTypeMap( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& typeMap ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+
+// ::com::sun::star::sdbc::XCloseable
+ virtual void SAL_CALL close( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+
+ // XMultiServiceFactory
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL createInstance( const ::rtl::OUString& aServiceSpecifier ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL createInstanceWithArguments( const ::rtl::OUString& ServiceSpecifier, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& Arguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getAvailableServiceNames( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XUsersSupplier
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL getUsers( ) throw(::com::sun::star::uno::RuntimeException);
+ // XGroupsSupplier
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL getGroups( ) throw(::com::sun::star::uno::RuntimeException);
+
+ // XConnectionTools
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdb::tools::XTableName > SAL_CALL createTableName( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdb::tools::XObjectNames > SAL_CALL getObjectNames( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdb::tools::XDataSourceMetaData > SAL_CALL getDataSourceMetaData( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL getFieldsByCommandDescriptor( ::sal_Int32 commandType, const ::rtl::OUString& command, ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& keepFieldsAlive ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XSingleSelectQueryComposer > SAL_CALL getComposer( ::sal_Int32 commandType, const ::rtl::OUString& command ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XTableUIProvider
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic > SAL_CALL getTableIcon( const ::rtl::OUString& TableName, ::sal_Int32 ColorMode ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL getTableEditor( const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::application::XDatabaseDocumentUI >& DocumentUI, const ::rtl::OUString& TableName ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+ // IRefreshListener
+ virtual void refresh(const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& _rToBeRefreshed);
+
+protected:
+ inline void checkDisposed() throw (::com::sun::star::lang::DisposedException)
+ {
+ if ( rBHelper.bDisposed || !m_xConnection.is() )
+ throw ::com::sun::star::lang::DisposedException();
+ }
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbcx::XTablesSupplier > getMasterTables();
+
+private:
+ /** checks whether or not there are naming conflicts between tables and queries
+ */
+ void impl_checkTableQueryNames_nothrow();
+
+ /** loads the XConnectionTools implementation which we forward the respective functionality to
+
+ @throws ::com::sun::star::uno::RuntimeException
+ if the implementation cannot be loaded
+
+ @postcond
+ m_xConnectionTools is nol <NULL/>
+ */
+ void impl_loadConnectionTools_throw();
+
+ /** reads the table filter and table type filter from the datasourfce
+ */
+ void impl_fillTableFilter();
+};
+
+//........................................................................
+} // namespace dbaccess
+//........................................................................
+
+#endif // _DBA_CORE_CONNECTION_HXX_
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/dataaccessdescriptor.cxx b/dbaccess/source/core/dataaccess/dataaccessdescriptor.cxx
new file mode 100644
index 000000000000..0a5432f79db7
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/dataaccessdescriptor.cxx
@@ -0,0 +1,328 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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"
+
+#include "dbastrings.hrc"
+#include "module_dba.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/sdb/CommandType.hpp>
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/sdb/XDataAccessDescriptorFactory.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/broadcasthelper.hxx>
+#include <comphelper/componentcontext.hxx>
+#include <comphelper/proparrhlp.hxx>
+#include <comphelper/propertycontainer.hxx>
+#include <comphelper/uno3.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include <cppuhelper/implbase2.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::lang::XServiceInfo;
+ using ::com::sun::star::lang::XMultiServiceFactory;
+ using ::com::sun::star::beans::XPropertySetInfo;
+ using ::com::sun::star::beans::Property;
+ using ::com::sun::star::sdbc::XConnection;
+ using ::com::sun::star::sdbc::XResultSet;
+ using ::com::sun::star::sdb::XDataAccessDescriptorFactory;
+ using ::com::sun::star::beans::XPropertySet;
+ using ::com::sun::star::uno::XComponentContext;
+ using ::com::sun::star::beans::PropertyValue;
+ /** === end UNO using === **/
+
+ namespace PropertyAttribute = ::com::sun::star::beans::PropertyAttribute;
+ namespace CommandType = ::com::sun::star::sdb::CommandType;
+
+ //====================================================================
+ //= DataAccessDescriptor
+ //====================================================================
+ typedef ::comphelper::OMutexAndBroadcastHelper DataAccessDescriptor_MutexBase;
+
+ typedef ::cppu::WeakImplHelper1 < XServiceInfo
+ > DataAccessDescriptor_TypeBase;
+
+ typedef ::comphelper::OPropertyContainer DataAccessDescriptor_PropertyBase;
+
+ class DataAccessDescriptor :public DataAccessDescriptor_MutexBase
+ ,public DataAccessDescriptor_TypeBase
+ ,public DataAccessDescriptor_PropertyBase
+ ,public ::comphelper::OPropertyArrayUsageHelper< DataAccessDescriptor >
+ {
+ public:
+ DataAccessDescriptor( const ::comphelper::ComponentContext& _rContext );
+
+ // UNO
+ DECLARE_XINTERFACE()
+ DECLARE_XTYPEPROVIDER()
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw (RuntimeException);
+ virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (RuntimeException);
+ virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (RuntimeException);
+
+ protected:
+ ~DataAccessDescriptor();
+
+ protected:
+ // XPropertySet
+ virtual Reference< XPropertySetInfo > SAL_CALL getPropertySetInfo() throw(RuntimeException);
+ virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
+
+ // OPropertyArrayUsageHelper
+ virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;
+
+ private:
+ ::comphelper::ComponentContext m_aContext;
+
+ // </properties>
+ ::rtl::OUString m_sDataSourceName;
+ ::rtl::OUString m_sDatabaseLocation;
+ ::rtl::OUString m_sConnectionResource;
+ Sequence< PropertyValue > m_aConnectionInfo;
+ Reference< XConnection > m_xActiveConnection;
+ ::rtl::OUString m_sCommand;
+ sal_Int32 m_nCommandType;
+ ::rtl::OUString m_sFilter;
+ ::rtl::OUString m_sOrder;
+ ::rtl::OUString m_sHavingClause;
+ ::rtl::OUString m_sGroupBy;
+ sal_Bool m_bEscapeProcessing;
+ Reference< XResultSet > m_xResultSet;
+ Sequence< Any > m_aSelection;
+ sal_Bool m_bBookmarkSelection;
+ ::rtl::OUString m_sColumnName;
+ Reference< XPropertySet > m_xColumn;
+ // </properties>
+ };
+
+#define REGISTER_PROPERTY( propname, member ) \
+ registerProperty( PROPERTY_##propname, PROPERTY_ID_##propname, PropertyAttribute::BOUND, &member, ::getCppuType( &member ) )
+
+ DataAccessDescriptor::DataAccessDescriptor( const ::comphelper::ComponentContext& _rContext )
+ :DataAccessDescriptor_MutexBase()
+ ,DataAccessDescriptor_TypeBase()
+ ,DataAccessDescriptor_PropertyBase( m_aBHelper )
+ ,m_aContext( _rContext )
+ ,m_sDataSourceName()
+ ,m_sDatabaseLocation()
+ ,m_sConnectionResource()
+ ,m_aConnectionInfo()
+ ,m_xActiveConnection()
+ ,m_sCommand()
+ ,m_nCommandType( CommandType::COMMAND )
+ ,m_sFilter()
+ ,m_sOrder()
+ ,m_sHavingClause()
+ ,m_sGroupBy()
+ ,m_bEscapeProcessing( sal_True )
+ ,m_xResultSet()
+ ,m_aSelection()
+ ,m_bBookmarkSelection( sal_True )
+ ,m_sColumnName()
+ ,m_xColumn()
+ {
+ REGISTER_PROPERTY( DATASOURCENAME, m_sDataSourceName );
+ REGISTER_PROPERTY( DATABASE_LOCATION, m_sDatabaseLocation );
+ REGISTER_PROPERTY( CONNECTION_RESOURCE, m_sConnectionResource );
+ REGISTER_PROPERTY( CONNECTION_INFO, m_aConnectionInfo );
+ REGISTER_PROPERTY( ACTIVE_CONNECTION, m_xActiveConnection );
+ REGISTER_PROPERTY( COMMAND, m_sCommand );
+ REGISTER_PROPERTY( COMMAND_TYPE, m_nCommandType );
+ REGISTER_PROPERTY( FILTER, m_sFilter );
+ REGISTER_PROPERTY( ORDER, m_sOrder );
+ REGISTER_PROPERTY( HAVING_CLAUSE, m_sHavingClause );
+ REGISTER_PROPERTY( GROUP_BY, m_sGroupBy );
+ REGISTER_PROPERTY( ESCAPE_PROCESSING, m_bEscapeProcessing );
+ REGISTER_PROPERTY( RESULT_SET, m_xResultSet );
+ REGISTER_PROPERTY( SELECTION, m_aSelection );
+ REGISTER_PROPERTY( BOOKMARK_SELECTION, m_bBookmarkSelection );
+ REGISTER_PROPERTY( COLUMN_NAME, m_sColumnName );
+ REGISTER_PROPERTY( COLUMN, m_xColumn );
+ }
+
+ DataAccessDescriptor::~DataAccessDescriptor()
+ {
+ }
+
+ IMPLEMENT_FORWARD_XINTERFACE2( DataAccessDescriptor, DataAccessDescriptor_TypeBase, DataAccessDescriptor_PropertyBase );
+
+ IMPLEMENT_FORWARD_XTYPEPROVIDER2( DataAccessDescriptor, DataAccessDescriptor_TypeBase, DataAccessDescriptor_PropertyBase );
+
+ ::rtl::OUString SAL_CALL DataAccessDescriptor::getImplementationName() throw (RuntimeException)
+ {
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.dba.DataAccessDescriptor" ) );
+ }
+
+ ::sal_Bool SAL_CALL DataAccessDescriptor::supportsService( const ::rtl::OUString& rServiceName ) throw (RuntimeException)
+ {
+ Sequence< ::rtl::OUString > aServices( getSupportedServiceNames() );
+ const ::rtl::OUString* pStart = aServices.getConstArray();
+ const ::rtl::OUString* pEnd = aServices.getConstArray() + aServices.getLength();
+ return ::std::find( pStart, pEnd, rServiceName ) != pEnd;
+ }
+
+ Sequence< ::rtl::OUString > SAL_CALL DataAccessDescriptor::getSupportedServiceNames( ) throw (RuntimeException)
+ {
+ Sequence< ::rtl::OUString > aServices(1);
+ aServices[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.DataAccessDescriptor" ) );
+ return aServices;
+ }
+
+ Reference< XPropertySetInfo > SAL_CALL DataAccessDescriptor::getPropertySetInfo() throw(RuntimeException)
+ {
+ Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
+ return xInfo;
+ }
+
+ ::cppu::IPropertyArrayHelper& DataAccessDescriptor::getInfoHelper()
+ {
+ return *getArrayHelper();
+ }
+
+ ::cppu::IPropertyArrayHelper* DataAccessDescriptor::createArrayHelper( ) const
+ {
+ Sequence< Property > aProps;
+ describeProperties( aProps );
+ return new ::cppu::OPropertyArrayHelper( aProps );
+ }
+
+ //====================================================================
+ //= DataAccessDescriptorFactory
+ //====================================================================
+ typedef ::cppu::WeakImplHelper2 < XServiceInfo
+ , XDataAccessDescriptorFactory
+ > DataAccessDescriptorFactory_Base;
+ class DataAccessDescriptorFactory : public DataAccessDescriptorFactory_Base
+ {
+ public:
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw (RuntimeException);
+ virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (RuntimeException);
+ virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (RuntimeException);
+
+ // XServiceInfo - static versions
+ static Sequence< ::rtl::OUString > getSupportedServiceNames_static(void) throw( RuntimeException );
+ static ::rtl::OUString getImplementationName_static(void) throw( RuntimeException );
+ static Reference< XInterface > Create(const Reference< XComponentContext >& _rxContext);
+ static ::rtl::OUString getSingletonName_static();
+
+ // XDataAccessDescriptorFactory
+ virtual Reference< XPropertySet > SAL_CALL createDataAccessDescriptor( ) throw (RuntimeException);
+
+ protected:
+ DataAccessDescriptorFactory( const Reference< XComponentContext >& _rxContext );
+ ~DataAccessDescriptorFactory();
+
+ private:
+ ::comphelper::ComponentContext m_aContext;
+ };
+
+ DataAccessDescriptorFactory::DataAccessDescriptorFactory( const Reference< XComponentContext >& _rxContext )
+ :m_aContext( _rxContext )
+ {
+ }
+
+ DataAccessDescriptorFactory::~DataAccessDescriptorFactory()
+ {
+ }
+
+ ::rtl::OUString DataAccessDescriptorFactory::getSingletonName_static()
+ {
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.DataAccessDescriptorFactory" ) );
+ }
+
+ Sequence< ::rtl::OUString > DataAccessDescriptorFactory::getSupportedServiceNames_static() throw( RuntimeException )
+ {
+ Sequence< ::rtl::OUString > aServices(1);
+ aServices[0] = getSingletonName_static();
+ return aServices;
+ }
+
+ ::rtl::OUString DataAccessDescriptorFactory::getImplementationName_static() throw( RuntimeException )
+ {
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.dba.DataAccessDescriptorFactory" ) );
+ }
+
+ Reference< XInterface > DataAccessDescriptorFactory::Create( const Reference< XComponentContext >& _rxContext )
+ {
+ return *( new DataAccessDescriptorFactory( _rxContext ) );
+ }
+
+ ::rtl::OUString SAL_CALL DataAccessDescriptorFactory::getImplementationName() throw (RuntimeException)
+ {
+ return getImplementationName_static();
+ }
+
+ ::sal_Bool SAL_CALL DataAccessDescriptorFactory::supportsService( const ::rtl::OUString& rServiceName ) throw (RuntimeException)
+ {
+ Sequence< ::rtl::OUString > aServices( getSupportedServiceNames_static() );
+ const ::rtl::OUString* pStart = aServices.getConstArray();
+ const ::rtl::OUString* pEnd = aServices.getConstArray() + aServices.getLength();
+ return ::std::find( pStart, pEnd, rServiceName ) != pEnd;
+ }
+
+ Sequence< ::rtl::OUString > SAL_CALL DataAccessDescriptorFactory::getSupportedServiceNames( ) throw (RuntimeException)
+ {
+ return getSupportedServiceNames_static();
+ }
+
+ Reference< XPropertySet > SAL_CALL DataAccessDescriptorFactory::createDataAccessDescriptor( ) throw (RuntimeException)
+ {
+ return new DataAccessDescriptor( m_aContext );
+ }
+
+} // namespace dbaccess
+
+extern "C" void SAL_CALL createRegistryInfo_DataAccessDescriptorFactory()
+{
+ static ::dba::OSingletonRegistration< ::dbaccess::DataAccessDescriptorFactory > aAutoRegistration;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/databasecontext.cxx b/dbaccess/source/core/dataaccess/databasecontext.cxx
new file mode 100644
index 000000000000..6fcf10a307d1
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/databasecontext.cxx
@@ -0,0 +1,770 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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"
+
+#include "apitools.hxx"
+#include "core_resource.hrc"
+#include "core_resource.hxx"
+#include "databasecontext.hxx"
+#include "databasedocument.hxx"
+#include "databaseregistrations.hxx"
+#include "datasource.hxx"
+#include "dbastrings.hrc"
+#include "module_dba.hxx"
+
+/** === being UNO includes === **/
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/document/MacroExecMode.hpp>
+#include <com/sun/star/document/XFilter.hpp>
+#include <com/sun/star/document/XImporter.hpp>
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/frame/XModel2.hpp>
+#include <com/sun/star/frame/XTerminateListener.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/registry/InvalidRegistryException.hpp>
+#include <com/sun/star/sdbc/XDataSource.hpp>
+#include <com/sun/star/task/InteractionClassification.hpp>
+#include <com/sun/star/ucb/InteractiveIOException.hpp>
+#include <com/sun/star/ucb/IOErrorCode.hpp>
+#include <com/sun/star/util/XCloseable.hpp>
+/** === end UNO includes === **/
+
+#include <basic/basmgr.hxx>
+#include <comphelper/enumhelper.hxx>
+#include <comphelper/evtlistenerhlp.hxx>
+#include <comphelper/namedvaluecollection.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/sequence.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <svl/filenotation.hxx>
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+#include <tools/fsys.hxx>
+#include <tools/urlobj.hxx>
+#include <ucbhelper/content.hxx>
+#include <unotools/confignode.hxx>
+#include <unotools/pathoptions.hxx>
+#include <unotools/sharedunocomponent.hxx>
+#include <list>
+#include <boost/bind.hpp>
+
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::document;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::registry;
+using namespace ::com::sun::star;
+using namespace ::cppu;
+using namespace ::osl;
+using namespace ::utl;
+
+using ::com::sun::star::task::InteractionClassification_ERROR;
+using ::com::sun::star::ucb::IOErrorCode_NO_FILE;
+using ::com::sun::star::ucb::InteractiveIOException;
+using ::com::sun::star::ucb::IOErrorCode_NOT_EXISTING;
+using ::com::sun::star::ucb::IOErrorCode_NOT_EXISTING_PATH;
+
+
+extern "C" void SAL_CALL createRegistryInfo_ODatabaseContext()
+{
+ static ::dba::OLegacySingletonRegistration< ::dbaccess::ODatabaseContext > aODatabaseContext_AutoRegistration;
+}
+
+namespace dbaccess
+{
+
+ typedef ::cppu::WeakImplHelper1 < XTerminateListener
+ > DatabaseDocumentLoader_Base;
+ class DatabaseDocumentLoader : public DatabaseDocumentLoader_Base
+ {
+ private:
+ Reference< XDesktop > m_xDesktop;
+ ::std::list< const ODatabaseModelImpl* > m_aDatabaseDocuments;
+
+ public:
+ DatabaseDocumentLoader( const comphelper::ComponentContext& _aContext);
+
+ inline void append(const ODatabaseModelImpl& _rModelImpl )
+ {
+ m_aDatabaseDocuments.push_back(&_rModelImpl);
+ }
+ inline void remove(const ODatabaseModelImpl& _rModelImpl) { m_aDatabaseDocuments.remove(&_rModelImpl); }
+
+ private:
+ // XTerminateListener
+ virtual void SAL_CALL queryTermination( const lang::EventObject& Event ) throw (TerminationVetoException, RuntimeException);
+ virtual void SAL_CALL notifyTermination( const lang::EventObject& Event ) throw (RuntimeException);
+ // XEventListener
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);
+ };
+
+ DatabaseDocumentLoader::DatabaseDocumentLoader( const comphelper::ComponentContext& _aContext )
+ {
+ acquire();
+ try
+ {
+ m_xDesktop.set( _aContext.createComponent( (rtl::OUString)SERVICE_FRAME_DESKTOP ), UNO_QUERY_THROW );
+ m_xDesktop->addTerminateListener( this );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ struct TerminateFunctor : ::std::unary_function<ODatabaseModelImpl* , void>
+ {
+ void operator()( const ODatabaseModelImpl* _pModelImpl ) const
+ {
+ try
+ {
+ const Reference< XModel2> xModel( _pModelImpl ->getModel_noCreate(),UNO_QUERY_THROW );
+ if ( !xModel->getControllers()->hasMoreElements() )
+ {
+ Reference<util::XCloseable> xCloseable(xModel,UNO_QUERY_THROW);
+ xCloseable->close(sal_False);
+ } // if ( !xModel->getControllers()->hasMoreElements() )
+ }
+ catch(const CloseVetoException&)
+ {
+ throw TerminationVetoException();
+ }
+ }
+ };
+
+ void SAL_CALL DatabaseDocumentLoader::queryTermination( const lang::EventObject& /*Event*/ ) throw (TerminationVetoException, RuntimeException)
+ {
+ ::std::list< const ODatabaseModelImpl* > aCopy(m_aDatabaseDocuments);
+ ::std::for_each(aCopy.begin(),aCopy.end(),TerminateFunctor());
+ }
+
+ void SAL_CALL DatabaseDocumentLoader::notifyTermination( const lang::EventObject& /*Event*/ ) throw (RuntimeException)
+ {
+ }
+
+ void SAL_CALL DatabaseDocumentLoader::disposing( const lang::EventObject& /*Source*/ ) throw (RuntimeException)
+ {
+ }
+
+//= ODatabaseContext
+//==========================================================================
+
+ODatabaseContext::ODatabaseContext( const Reference< XComponentContext >& _rxContext )
+ :DatabaseAccessContext_Base(m_aMutex)
+ ,m_aContext( _rxContext )
+ ,m_aContainerListeners(m_aMutex)
+{
+ m_pDatabaseDocumentLoader = new DatabaseDocumentLoader( m_aContext );
+ ::basic::BasicManagerRepository::registerCreationListener( *this );
+
+ osl_incrementInterlockedCount( &m_refCount );
+ {
+ m_xDBRegistrationAggregate.set( createDataSourceRegistrations( m_aContext ), UNO_SET_THROW );
+ m_xDatabaseRegistrations.set( m_xDBRegistrationAggregate, UNO_QUERY_THROW );
+
+ m_xDBRegistrationAggregate->setDelegator( *this );
+ }
+ osl_decrementInterlockedCount( &m_refCount );
+}
+
+ODatabaseContext::~ODatabaseContext()
+{
+ ::basic::BasicManagerRepository::revokeCreationListener( *this );
+ if ( m_pDatabaseDocumentLoader )
+ m_pDatabaseDocumentLoader->release();
+
+ m_xDBRegistrationAggregate->setDelegator( NULL );
+ m_xDBRegistrationAggregate.clear();
+ m_xDatabaseRegistrations.clear();
+}
+
+// Helper
+rtl::OUString ODatabaseContext::getImplementationName_static() throw( RuntimeException )
+
+{
+ return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.dba.ODatabaseContext"));
+}
+
+Reference< XInterface > ODatabaseContext::Create(const Reference< XComponentContext >& _rxContext)
+{
+ return *( new ODatabaseContext( _rxContext ) );
+}
+
+Sequence< rtl::OUString > ODatabaseContext::getSupportedServiceNames_static(void) throw( RuntimeException )
+{
+ Sequence< ::rtl::OUString > aSNS( 1 );
+ aSNS[0] = SERVICE_SDB_DATABASECONTEXT;
+ return aSNS;
+}
+
+// XServiceInfo
+rtl::OUString ODatabaseContext::getImplementationName( ) throw(RuntimeException)
+{
+ return getImplementationName_static();
+}
+
+sal_Bool ODatabaseContext::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException)
+{
+ return ::comphelper::findValue(getSupportedServiceNames(), _rServiceName, sal_True).getLength() != 0;
+}
+
+Sequence< ::rtl::OUString > ODatabaseContext::getSupportedServiceNames( ) throw (RuntimeException)
+{
+ return getSupportedServiceNames_static();
+}
+
+Reference< XInterface > ODatabaseContext::impl_createNewDataSource()
+{
+ ::rtl::Reference<ODatabaseModelImpl> pImpl( new ODatabaseModelImpl( m_aContext.getLegacyServiceFactory(), *this ) );
+ Reference< XDataSource > xDataSource( pImpl->getOrCreateDataSource() );
+
+ return xDataSource.get();
+}
+
+Reference< XInterface > SAL_CALL ODatabaseContext::createInstance( ) throw (Exception, RuntimeException)
+{
+ // for convenience of the API user, we ensure the document is fully initialized (effectively: XLoadable::initNew
+ // has been called at the DatabaseDocument).
+ return impl_createNewDataSource();
+}
+
+Reference< XInterface > SAL_CALL ODatabaseContext::createInstanceWithArguments( const Sequence< Any >& _rArguments ) throw (Exception, RuntimeException)
+{
+ ::comphelper::NamedValueCollection aArgs( _rArguments );
+ ::rtl::OUString sURL = aArgs.getOrDefault( (::rtl::OUString)INFO_POOLURL, ::rtl::OUString() );
+
+ Reference< XInterface > xDataSource;
+ if ( sURL.getLength() )
+ xDataSource = getObject( sURL );
+
+ if ( !xDataSource.is() )
+ xDataSource = impl_createNewDataSource();
+
+ return xDataSource;
+}
+
+// DatabaseAccessContext_Base
+void ODatabaseContext::disposing()
+{
+ // notify our listener
+ com::sun::star::lang::EventObject aDisposeEvent(static_cast< XContainer* >(this));
+ m_aContainerListeners.disposeAndClear(aDisposeEvent);
+
+ // dispose the data sources
+ ObjectCache::iterator aEnd = m_aDatabaseObjects.end();
+ for ( ObjectCache::iterator aIter = m_aDatabaseObjects.begin();
+ aIter != aEnd;
+ ++aIter
+ )
+ {
+ aIter->second->dispose();
+ }
+ m_aDatabaseObjects.clear();
+}
+
+// XNamingService
+Reference< XInterface > ODatabaseContext::getRegisteredObject(const rtl::OUString& _rName) throw( Exception, RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(DatabaseAccessContext_Base::rBHelper.bDisposed);
+
+ ::rtl::OUString sURL( getDatabaseLocation( _rName ) );
+
+ if ( !sURL.getLength() )
+ // there is a registration for this name, but no URL
+ throw IllegalArgumentException();
+
+ // check if URL is already loaded
+ Reference< XInterface > xExistent = getObject( sURL );
+ if ( xExistent.is() )
+ return xExistent;
+
+ return loadObjectFromURL( _rName, sURL );
+}
+
+Reference< XInterface > ODatabaseContext::loadObjectFromURL(const ::rtl::OUString& _rName,const ::rtl::OUString& _sURL)
+{
+ INetURLObject aURL( _sURL );
+ if ( aURL.GetProtocol() == INET_PROT_NOT_VALID )
+ throw NoSuchElementException( _rName, *this );
+
+ try
+ {
+ ::ucbhelper::Content aContent( _sURL, NULL );
+ if ( !aContent.isDocument() )
+ throw InteractiveIOException(
+ _sURL, *this, InteractionClassification_ERROR, IOErrorCode_NO_FILE
+ );
+ }
+ catch ( const InteractiveIOException& e )
+ {
+ if ( ( e.Code == IOErrorCode_NO_FILE )
+ || ( e.Code == IOErrorCode_NOT_EXISTING )
+ || ( e.Code == IOErrorCode_NOT_EXISTING_PATH )
+ )
+ {
+ // #i40463# #i39187#
+ String sErrorMessage( DBACORE_RESSTRING( RID_STR_FILE_DOES_NOT_EXIST ) );
+ ::svt::OFileNotation aTransformer( _sURL );
+ sErrorMessage.SearchAndReplaceAscii( "$file$", aTransformer.get( ::svt::OFileNotation::N_SYSTEM ) );
+
+ SQLException aError;
+ aError.Message = sErrorMessage;
+
+ throw WrappedTargetException( _sURL, *this, makeAny( aError ) );
+ }
+ throw WrappedTargetException( _sURL, *this, ::cppu::getCaughtException() );
+ }
+ catch( const Exception& )
+ {
+ throw WrappedTargetException( _sURL, *this, ::cppu::getCaughtException() );
+ }
+
+ OSL_ENSURE( m_aDatabaseObjects.find( _sURL ) == m_aDatabaseObjects.end(),
+ "ODatabaseContext::loadObjectFromURL: not intended for already-cached objects!" );
+
+ ::rtl::Reference< ODatabaseModelImpl > pModelImpl;
+ {
+ pModelImpl.set( new ODatabaseModelImpl( _rName, m_aContext.getLegacyServiceFactory(), *this ) );
+
+ Reference< XModel > xModel( pModelImpl->createNewModel_deliverOwnership( false ), UNO_SET_THROW );
+ Reference< XLoadable > xLoad( xModel, UNO_QUERY_THROW );
+
+ ::comphelper::NamedValueCollection aArgs;
+ aArgs.put( "URL", _sURL );
+ aArgs.put( "MacroExecutionMode", MacroExecMode::USE_CONFIG );
+ aArgs.put( "InteractionHandler", m_aContext.createComponent( "com.sun.star.task.InteractionHandler" ) );
+
+ Sequence< PropertyValue > aResource( aArgs.getPropertyValues() );
+ xLoad->load( aResource );
+ xModel->attachResource( _sURL, aResource );
+
+ ::utl::CloseableComponent aEnsureClose( xModel );
+ }
+
+ setTransientProperties( _sURL, *pModelImpl );
+
+ return pModelImpl->getOrCreateDataSource().get();
+}
+
+void ODatabaseContext::appendAtTerminateListener(const ODatabaseModelImpl& _rDataSourceModel)
+{
+ m_pDatabaseDocumentLoader->append(_rDataSourceModel);
+}
+
+void ODatabaseContext::removeFromTerminateListener(const ODatabaseModelImpl& _rDataSourceModel)
+{
+ m_pDatabaseDocumentLoader->remove(_rDataSourceModel);
+}
+
+void ODatabaseContext::setTransientProperties(const ::rtl::OUString& _sURL, ODatabaseModelImpl& _rDataSourceModel )
+{
+ if ( m_aDatasourceProperties.end() == m_aDatasourceProperties.find(_sURL) )
+ return;
+ try
+ {
+ ::rtl::OUString sAuthFailedPassword;
+ Reference< XPropertySet > xDSProps( _rDataSourceModel.getOrCreateDataSource(), UNO_QUERY_THROW );
+ const Sequence< PropertyValue >& rSessionPersistentProps = m_aDatasourceProperties[_sURL];
+ const PropertyValue* pProp = rSessionPersistentProps.getConstArray();
+ const PropertyValue* pPropsEnd = rSessionPersistentProps.getConstArray() + rSessionPersistentProps.getLength();
+ for ( ; pProp != pPropsEnd; ++pProp )
+ {
+ if ( pProp->Name.equalsAscii( "AuthFailedPassword" ) )
+ {
+ OSL_VERIFY( pProp->Value >>= sAuthFailedPassword );
+ }
+ else
+ {
+ xDSProps->setPropertyValue( pProp->Name, pProp->Value );
+ }
+ }
+
+ _rDataSourceModel.m_sFailedPassword = sAuthFailedPassword;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+}
+
+void ODatabaseContext::registerObject(const rtl::OUString& _rName, const Reference< XInterface > & _rxObject) throw( Exception, RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(DatabaseAccessContext_Base::rBHelper.bDisposed);
+
+ if ( !_rName.getLength() )
+ throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
+
+ Reference< XDocumentDataSource > xDocDataSource( _rxObject, UNO_QUERY );
+ Reference< XModel > xModel( xDocDataSource.is() ? xDocDataSource->getDatabaseDocument() : Reference< XOfficeDatabaseDocument >(), UNO_QUERY );
+ if ( !xModel.is() )
+ throw IllegalArgumentException( ::rtl::OUString(), *this, 2 );
+
+ ::rtl::OUString sURL = xModel->getURL();
+ if ( !sURL.getLength() )
+ throw IllegalArgumentException( DBACORE_RESSTRING( RID_STR_DATASOURCE_NOT_STORED ), *this, 2 );
+
+ registerDatabaseLocation( _rName, sURL );
+
+ ODatabaseSource::setName( xDocDataSource, _rName, ODatabaseSource::DBContextAccess() );
+
+ // notify our container listeners
+ ContainerEvent aEvent(static_cast<XContainer*>(this), makeAny(_rName), makeAny(_rxObject), Any());
+ m_aContainerListeners.notifyEach( &XContainerListener::elementInserted, aEvent );
+}
+
+void ODatabaseContext::storeTransientProperties( ODatabaseModelImpl& _rModelImpl)
+{
+ Reference< XPropertySet > xSource( _rModelImpl.getOrCreateDataSource(), UNO_QUERY );
+ ::comphelper::NamedValueCollection aRememberProps;
+
+ try
+ {
+ // get the info about the properties, check which ones are transient and not readonly
+ Reference< XPropertySetInfo > xSetInfo;
+ if (xSource.is())
+ xSetInfo = xSource->getPropertySetInfo();
+ Sequence< Property > aProperties;
+ if (xSetInfo.is())
+ aProperties = xSetInfo->getProperties();
+
+ if (aProperties.getLength())
+ {
+ const Property* pProperties = aProperties.getConstArray();
+ for ( sal_Int32 i=0; i<aProperties.getLength(); ++i, ++pProperties )
+ {
+ if ( ( ( pProperties->Attributes & PropertyAttribute::TRANSIENT) != 0 )
+ && ( ( pProperties->Attributes & PropertyAttribute::READONLY) == 0 )
+ )
+ {
+ // found such a property
+ aRememberProps.put( pProperties->Name, xSource->getPropertyValue( pProperties->Name ) );
+ }
+ }
+ }
+ }
+ catch ( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ // additionally, remember the "failed password", which is not available as property
+ // #i86178# / 2008-02-19 / frank.schoenheit@sun.com
+ aRememberProps.put( "AuthFailedPassword", _rModelImpl.m_sFailedPassword );
+
+ ::rtl::OUString sDocumentURL( _rModelImpl.getURL() );
+ if ( m_aDatabaseObjects.find( sDocumentURL ) != m_aDatabaseObjects.end() )
+ {
+ m_aDatasourceProperties[ sDocumentURL ] = aRememberProps.getPropertyValues();
+ }
+ else if ( m_aDatabaseObjects.find( _rModelImpl.m_sName ) != m_aDatabaseObjects.end() )
+ {
+ OSL_ENSURE( false, "ODatabaseContext::storeTransientProperties: a database document register by name? This shouldn't happen anymore!" );
+ // all the code should have been changed so that registration is by URL only
+ m_aDatasourceProperties[ _rModelImpl.m_sName ] = aRememberProps.getPropertyValues();
+ }
+ else
+ {
+ OSL_ENSURE( ( sDocumentURL.getLength() == 0 ) && ( _rModelImpl.m_sName.getLength() == 0 ),
+ "ODatabaseContext::storeTransientProperties: a non-empty data source which I do not know?!" );
+ }
+}
+
+void SAL_CALL ODatabaseContext::addContainerListener( const Reference< XContainerListener >& _rxListener ) throw(RuntimeException)
+{
+ m_aContainerListeners.addInterface(_rxListener);
+}
+
+void SAL_CALL ODatabaseContext::removeContainerListener( const Reference< XContainerListener >& _rxListener ) throw(RuntimeException)
+{
+ m_aContainerListeners.removeInterface(_rxListener);
+}
+
+void ODatabaseContext::revokeObject(const rtl::OUString& _rName) throw( Exception, RuntimeException )
+{
+ ClearableMutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(DatabaseAccessContext_Base::rBHelper.bDisposed);
+
+ ::rtl::OUString sURL = getDatabaseLocation( _rName );
+
+ revokeDatabaseLocation( _rName );
+ // will throw if something goes wrong
+
+ if ( m_aDatabaseObjects.find( _rName ) != m_aDatabaseObjects.end() )
+ {
+ m_aDatasourceProperties[ sURL ] = m_aDatasourceProperties[ _rName ];
+ }
+
+ // check if URL is already loaded
+ ObjectCacheIterator aExistent = m_aDatabaseObjects.find( sURL );
+ if ( aExistent != m_aDatabaseObjects.end() )
+ m_aDatabaseObjects.erase( aExistent );
+
+ // notify our container listeners
+ ContainerEvent aEvent( *this, makeAny( _rName ), Any(), Any() );
+ aGuard.clear();
+ m_aContainerListeners.notifyEach( &XContainerListener::elementRemoved, aEvent );
+}
+
+::sal_Bool SAL_CALL ODatabaseContext::hasRegisteredDatabase( const ::rtl::OUString& _Name ) throw (IllegalArgumentException, RuntimeException)
+{
+ return m_xDatabaseRegistrations->hasRegisteredDatabase( _Name );
+}
+
+Sequence< ::rtl::OUString > SAL_CALL ODatabaseContext::getRegistrationNames() throw (RuntimeException)
+{
+ return m_xDatabaseRegistrations->getRegistrationNames();
+}
+
+::rtl::OUString SAL_CALL ODatabaseContext::getDatabaseLocation( const ::rtl::OUString& _Name ) throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
+{
+ return m_xDatabaseRegistrations->getDatabaseLocation( _Name );
+}
+
+void SAL_CALL ODatabaseContext::registerDatabaseLocation( const ::rtl::OUString& _Name, const ::rtl::OUString& _Location ) throw (IllegalArgumentException, ElementExistException, RuntimeException)
+{
+ m_xDatabaseRegistrations->registerDatabaseLocation( _Name, _Location );
+}
+
+void SAL_CALL ODatabaseContext::revokeDatabaseLocation( const ::rtl::OUString& _Name ) throw (IllegalArgumentException, NoSuchElementException, IllegalAccessException, RuntimeException)
+{
+ m_xDatabaseRegistrations->revokeDatabaseLocation( _Name );
+}
+
+void SAL_CALL ODatabaseContext::changeDatabaseLocation( const ::rtl::OUString& _Name, const ::rtl::OUString& _NewLocation ) throw (IllegalArgumentException, NoSuchElementException, IllegalAccessException, RuntimeException)
+{
+ m_xDatabaseRegistrations->changeDatabaseLocation( _Name, _NewLocation );
+}
+
+::sal_Bool SAL_CALL ODatabaseContext::isDatabaseRegistrationReadOnly( const ::rtl::OUString& _Name ) throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
+{
+ return m_xDatabaseRegistrations->isDatabaseRegistrationReadOnly( _Name );
+}
+
+void SAL_CALL ODatabaseContext::addDatabaseRegistrationsListener( const Reference< XDatabaseRegistrationsListener >& _Listener ) throw (RuntimeException)
+{
+ m_xDatabaseRegistrations->addDatabaseRegistrationsListener( _Listener );
+}
+
+void SAL_CALL ODatabaseContext::removeDatabaseRegistrationsListener( const Reference< XDatabaseRegistrationsListener >& _Listener ) throw (RuntimeException)
+{
+ m_xDatabaseRegistrations->removeDatabaseRegistrationsListener( _Listener );
+}
+
+// ::com::sun::star::container::XElementAccess
+Type ODatabaseContext::getElementType( ) throw(RuntimeException)
+{
+ return::getCppuType(static_cast<Reference<XDataSource>*>(NULL));
+}
+
+sal_Bool ODatabaseContext::hasElements(void) throw( RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(DatabaseAccessContext_Base::rBHelper.bDisposed);
+
+ return 0 != getElementNames().getLength();
+}
+
+// ::com::sun::star::container::XEnumerationAccess
+Reference< ::com::sun::star::container::XEnumeration > ODatabaseContext::createEnumeration(void) throw( RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+ return new ::comphelper::OEnumerationByName(static_cast<XNameAccess*>(this));
+}
+
+// ::com::sun::star::container::XNameAccess
+Any ODatabaseContext::getByName(const rtl::OUString& _rName) throw( NoSuchElementException,
+ WrappedTargetException, RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(DatabaseAccessContext_Base::rBHelper.bDisposed);
+ if ( !_rName.getLength() )
+ throw NoSuchElementException(_rName, *this);
+
+ try
+ {
+ Reference< XInterface > xExistent = getObject( _rName );
+ if ( xExistent.is() )
+ return makeAny( xExistent );
+
+ // see whether this is an registered name
+ ::rtl::OUString sURL;
+ if ( hasRegisteredDatabase( _rName ) )
+ {
+ sURL = getDatabaseLocation( _rName );
+ // is the object cached under its URL?
+ xExistent = getObject( sURL );
+ }
+ else
+ // interpret the name as URL
+ sURL = _rName;
+
+ if ( !xExistent.is() )
+ // try to load this as URL
+ xExistent = loadObjectFromURL( _rName, sURL );
+ return makeAny( xExistent );
+ }
+ catch (NoSuchElementException&)
+ { // let these exceptions through
+ throw;
+ }
+ catch (WrappedTargetException&)
+ { // let these exceptions through
+ throw;
+ }
+ catch (RuntimeException&)
+ { // let these exceptions through
+ throw;
+ }
+ catch (Exception& e)
+ { // exceptions other than the speciafied ones -> wrap
+ Any aError = ::cppu::getCaughtException();
+ throw WrappedTargetException(_rName, *this, aError );
+ }
+}
+
+Sequence< rtl::OUString > ODatabaseContext::getElementNames(void) throw( RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(DatabaseAccessContext_Base::rBHelper.bDisposed);
+
+ return getRegistrationNames();
+}
+
+sal_Bool ODatabaseContext::hasByName(const rtl::OUString& _rName) throw( RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(DatabaseAccessContext_Base::rBHelper.bDisposed);
+
+ return hasRegisteredDatabase( _rName );
+}
+
+Reference< XInterface > ODatabaseContext::getObject( const ::rtl::OUString& _rURL )
+{
+ ObjectCacheIterator aFind = m_aDatabaseObjects.find( _rURL );
+ Reference< XInterface > xExistent;
+ if ( aFind != m_aDatabaseObjects.end() )
+ xExistent = aFind->second->getOrCreateDataSource();
+ return xExistent;
+}
+
+void ODatabaseContext::registerDatabaseDocument( ODatabaseModelImpl& _rModelImpl )
+{
+ ::rtl::OUString sURL( _rModelImpl.getURL() );
+#if OSL_DEBUG_LEVEL > 1
+ OSL_TRACE( "DatabaseContext: registering %s", ::rtl::OUStringToOString( sURL, RTL_TEXTENCODING_UTF8 ).getStr() );
+#endif
+ if ( m_aDatabaseObjects.find( sURL ) == m_aDatabaseObjects.end() )
+ {
+ m_aDatabaseObjects[ sURL ] = &_rModelImpl;
+ setTransientProperties( sURL, _rModelImpl );
+ }
+ else
+ OSL_ENSURE( false, "ODatabaseContext::registerDatabaseDocument: already have an object registered for this URL!" );
+}
+
+void ODatabaseContext::revokeDatabaseDocument( const ODatabaseModelImpl& _rModelImpl )
+{
+ ::rtl::OUString sURL( _rModelImpl.getURL() );
+#if OSL_DEBUG_LEVEL > 1
+ OSL_TRACE( "DatabaseContext: deregistering %s", ::rtl::OUStringToOString( sURL, RTL_TEXTENCODING_UTF8 ).getStr() );
+#endif
+ m_aDatabaseObjects.erase( sURL );
+}
+
+void ODatabaseContext::databaseDocumentURLChange( const ::rtl::OUString& _rOldURL, const ::rtl::OUString& _rNewURL )
+{
+#if OSL_DEBUG_LEVEL > 1
+ OSL_TRACE( "DatabaseContext: changing registration from %s to %s",
+ ::rtl::OUStringToOString( _rOldURL, RTL_TEXTENCODING_UTF8 ).getStr(),
+ ::rtl::OUStringToOString( _rNewURL, RTL_TEXTENCODING_UTF8 ).getStr() );
+#endif
+ ObjectCache::iterator oldPos = m_aDatabaseObjects.find( _rOldURL );
+ ENSURE_OR_THROW( oldPos != m_aDatabaseObjects.end(), "illegal old database document URL" );
+ ObjectCache::iterator newPos = m_aDatabaseObjects.find( _rNewURL );
+ ENSURE_OR_THROW( newPos == m_aDatabaseObjects.end(), "illegal new database document URL" );
+
+ m_aDatabaseObjects[ _rNewURL ] = oldPos->second;
+ m_aDatabaseObjects.erase( oldPos );
+}
+
+sal_Int64 SAL_CALL ODatabaseContext::getSomething( const Sequence< sal_Int8 >& rId ) throw(RuntimeException)
+{
+ if (rId.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(), rId.getConstArray(), 16 ) )
+ return reinterpret_cast<sal_Int64>(this);
+
+ return 0;
+}
+
+Sequence< sal_Int8 > ODatabaseContext::getUnoTunnelImplementationId()
+{
+ static ::cppu::OImplementationId * pId = 0;
+ if (! pId)
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if (! pId)
+ {
+ static ::cppu::OImplementationId aId;
+ pId = &aId;
+ }
+ }
+ return pId->getImplementationId();
+}
+
+void ODatabaseContext::onBasicManagerCreated( const Reference< XModel >& _rxForDocument, BasicManager& _rBasicManager )
+{
+ // if it's a database document ...
+ Reference< XOfficeDatabaseDocument > xDatabaseDocument( _rxForDocument, UNO_QUERY );
+ // ... or a sub document of a database document ...
+ if ( !xDatabaseDocument.is() )
+ {
+ Reference< XChild > xDocAsChild( _rxForDocument, UNO_QUERY );
+ if ( xDocAsChild.is() )
+ xDatabaseDocument.set( xDocAsChild->getParent(), UNO_QUERY );
+ }
+
+ // ... whose BasicManager has just been created, then add the global DatabaseDocument variable to its scope.
+ if ( xDatabaseDocument.is() )
+ _rBasicManager.SetGlobalUNOConstant( "ThisDatabaseDocument", makeAny( xDatabaseDocument ) );
+}
+
+} // namespace dbaccess
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/databasecontext.hxx b/dbaccess/source/core/dataaccess/databasecontext.hxx
new file mode 100644
index 000000000000..71d5fb4ebc23
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/databasecontext.hxx
@@ -0,0 +1,214 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _DBA_COREDATAACCESS_DATABASECONTEXT_HXX_
+#define _DBA_COREDATAACCESS_DATABASECONTEXT_HXX_
+
+#include "ModelImpl.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/container/ElementExistException.hpp>
+#include <com/sun/star/container/XContainer.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/lang/XEventListener.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/lang/XUnoTunnel.hpp>
+#include <com/sun/star/sdb/XDatabaseEnvironment.hpp>
+#include <com/sun/star/sdb/XDatabaseRegistrations.hpp>
+#include <com/sun/star/uno/XNamingService.hpp>
+#include <com/sun/star/uno/XAggregation.hpp>
+/** === end UNO includes === **/
+
+#include <basic/basicmanagerrepository.hxx>
+#include <comphelper/componentcontext.hxx>
+#include <comphelper/stl_types.hxx>
+#include <cppuhelper/compbase8.hxx>
+#include <cppuhelper/interfacecontainer.hxx>
+
+#include <boost/shared_ptr.hpp>
+
+// needed for registration
+namespace com { namespace sun { namespace star {
+ namespace lang
+ {
+ class XMultiServiceFactory;
+ class IllegalArgumentException;
+ }
+} } }
+
+//........................................................................
+namespace dbaccess
+{
+//........................................................................
+class DatabaseDocumentLoader;
+//============================================================
+//= ODatabaseContext
+//============================================================
+::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >
+ ODatabaseContext_CreateInstance(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&);
+
+typedef ::cppu::WeakComponentImplHelper8 < ::com::sun::star::lang::XServiceInfo
+ , ::com::sun::star::container::XEnumerationAccess
+ , ::com::sun::star::container::XNameAccess
+ , ::com::sun::star::uno::XNamingService
+ , ::com::sun::star::container::XContainer
+ , ::com::sun::star::lang::XSingleServiceFactory
+ , ::com::sun::star::lang::XUnoTunnel
+ , ::com::sun::star::sdb::XDatabaseRegistrations
+ > DatabaseAccessContext_Base;
+
+class ODatabaseContext :public DatabaseAccessContext_Base
+ ,public ::basic::BasicManagerCreationListener
+{
+private:
+ /** loads the given object from the given URL
+ @throws WrappedTargetException
+ if an error occurs accessing the URL via the UCB
+ */
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > loadObjectFromURL(const ::rtl::OUString& _rName,const ::rtl::OUString& _sURL);
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > getObject( const ::rtl::OUString& _rURL );
+
+ /** sets all properties which were transient at the data source. e.g. password
+ @param _sURL The file URL of the data source
+ @param _xObject The data source itself.
+ */
+ void setTransientProperties(const ::rtl::OUString& _sURL, ODatabaseModelImpl& _rDataSourceModel );
+
+ /** creates a new data source
+ */
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >
+ impl_createNewDataSource();
+
+protected:
+ ::osl::Mutex m_aMutex;
+ ::comphelper::ComponentContext m_aContext;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XAggregation >
+ m_xDBRegistrationAggregate;
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XDatabaseRegistrations >
+ m_xDatabaseRegistrations;
+
+ DECLARE_STL_USTRINGACCESS_MAP( ODatabaseModelImpl*, ObjectCache );
+ ObjectCache m_aDatabaseObjects;
+
+ DECLARE_STL_USTRINGACCESS_MAP( ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >, PropertyCache );
+ PropertyCache m_aDatasourceProperties;
+ // as we hold our data sources weak, we have to cache all properties on the data sources which are
+ // transient but stored as long as the session lasts. The database context is the session (as it lives
+ // as long as the session does), but the data sources may die before the session does, and then be
+ // recreated afterwards. So it's our (the context's) responsibility to store the session-persistent
+ // properties.
+
+ ::cppu::OInterfaceContainerHelper m_aContainerListeners;
+ DatabaseDocumentLoader* m_pDatabaseDocumentLoader;
+
+public:
+ ODatabaseContext( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& );
+ virtual ~ODatabaseContext();
+
+
+ // OComponentHelper
+ virtual void SAL_CALL disposing(void);
+
+ // XSingleServiceFactory
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL createInstance( ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL createInstanceWithArguments( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& _rArguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo - static methods
+ static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_static(void) throw( ::com::sun::star::uno::RuntimeException );
+ static ::rtl::OUString getImplementationName_static(void) throw( ::com::sun::star::uno::RuntimeException );
+ static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >
+ SAL_CALL Create(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >&);
+
+ // XElementAccess
+ virtual ::com::sun::star::uno::Type SAL_CALL getElementType( ) throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasElements( ) throw(::com::sun::star::uno::RuntimeException);
+
+ // XEnumerationAccess
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumeration > SAL_CALL createEnumeration( ) throw(::com::sun::star::uno::RuntimeException);
+
+ // XNameAccess
+ virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( ) throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw(::com::sun::star::uno::RuntimeException);
+
+ // XNamingService
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL getRegisteredObject( const ::rtl::OUString& Name ) throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL registerObject( const ::rtl::OUString& Name, const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& Object ) throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL revokeObject( const ::rtl::OUString& Name ) throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+
+ // XDatabaseRegistrations
+ virtual ::sal_Bool SAL_CALL hasRegisteredDatabase( const ::rtl::OUString& Name ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getRegistrationNames() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getDatabaseLocation( const ::rtl::OUString& Name ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL registerDatabaseLocation( const ::rtl::OUString& Name, const ::rtl::OUString& Location ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL revokeDatabaseLocation( const ::rtl::OUString& Name ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL changeDatabaseLocation( const ::rtl::OUString& Name, const ::rtl::OUString& NewLocation ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL isDatabaseRegistrationReadOnly( const ::rtl::OUString& Name ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addDatabaseRegistrationsListener( const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XDatabaseRegistrationsListener >& Listener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeDatabaseRegistrationsListener( const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XDatabaseRegistrationsListener >& Listener ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XContainer
+ virtual void SAL_CALL addContainerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener >& xListener ) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeContainerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener >& xListener ) throw(::com::sun::star::uno::RuntimeException);
+
+ // com::sun::star::lang::XUnoTunnel
+ virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) throw(::com::sun::star::uno::RuntimeException);
+ static ::com::sun::star::uno::Sequence< sal_Int8 > getUnoTunnelImplementationId();
+
+ void registerDatabaseDocument( ODatabaseModelImpl& _rModelImpl);
+ void revokeDatabaseDocument( const ODatabaseModelImpl& _rModelImpl);
+ void databaseDocumentURLChange(const ::rtl::OUString& _sOldName, const ::rtl::OUString& _sNewName);
+ void storeTransientProperties( ODatabaseModelImpl& _rModelImpl);
+ void appendAtTerminateListener(const ODatabaseModelImpl& _rDataSourceModel);
+ void removeFromTerminateListener(const ODatabaseModelImpl& _rDataSourceModel);
+
+private:
+ // BasicManagerCreationListener
+ virtual void onBasicManagerCreated(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& _rxForDocument,
+ BasicManager& _rBasicManager
+ );
+};
+
+//........................................................................
+} // namespace dbaccess
+//........................................................................
+
+#endif // _DBA_COREDATAACCESS_DATABASECONTEXT_HXX_
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/databasedocument.cxx b/dbaccess/source/core/dataaccess/databasedocument.cxx
new file mode 100644
index 000000000000..46a82018781f
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/databasedocument.cxx
@@ -0,0 +1,2092 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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"
+
+#include "core_resource.hxx"
+#include "core_resource.hrc"
+#include "datasource.hxx"
+#include "databasedocument.hxx"
+#include "dbastrings.hrc"
+#include "module_dba.hxx"
+#include "documenteventexecutor.hxx"
+#include "databasecontext.hxx"
+#include "documentcontainer.hxx"
+#include "sdbcoretools.hxx"
+#include "recovery/dbdocrecovery.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/beans/Optional.hpp>
+#include <com/sun/star/document/XExporter.hpp>
+#include <com/sun/star/document/XFilter.hpp>
+#include <com/sun/star/document/XImporter.hpp>
+#include <com/sun/star/embed/EntryInitModes.hpp>
+#include <com/sun/star/embed/XEmbedPersist.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/embed/XTransactionBroadcaster.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XTruncate.hpp>
+#include <com/sun/star/script/provider/XScriptProviderFactory.hpp>
+#include <com/sun/star/task/ErrorCodeIOException.hpp>
+#include <com/sun/star/task/XStatusIndicator.hpp>
+#include <com/sun/star/task/XStatusIndicatorFactory.hpp>
+#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
+#include <com/sun/star/ui/XUIConfigurationStorage.hpp>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
+#include <com/sun/star/ucb/XContent.hpp>
+#include <com/sun/star/sdb/application/XDatabaseDocumentUI.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/documentconstants.hxx>
+#include <comphelper/enumhelper.hxx>
+#include <comphelper/genericpropertyset.hxx>
+#include <comphelper/interaction.hxx>
+#include <comphelper/mediadescriptor.hxx>
+#include <comphelper/namedvaluecollection.hxx>
+#include <comphelper/numberedcollection.hxx>
+#include <comphelper/property.hxx>
+#include <comphelper/storagehelper.hxx>
+#include <comphelper/genericpropertyset.hxx>
+#include <comphelper/property.hxx>
+
+#include <connectivity/dbtools.hxx>
+
+#include <cppuhelper/exc_hlp.hxx>
+#include <framework/titlehelper.hxx>
+#include <unotools/saveopt.hxx>
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+#include <tools/errcode.hxx>
+#include <tools/urlobj.hxx>
+
+#include <boost/bind.hpp>
+
+#include <algorithm>
+#include <functional>
+#include <list>
+
+#define MAP_LEN(x) x, sizeof(x) - 1
+
+#define MAP_LEN(x) x, sizeof(x) - 1
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::document;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::embed;
+using namespace ::com::sun::star::task;
+using namespace ::com::sun::star::view;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::script;
+using namespace ::com::sun::star::script::provider;
+using namespace ::com::sun::star::ui;
+using namespace ::cppu;
+using namespace ::osl;
+
+using ::com::sun::star::awt::XWindow;
+using ::com::sun::star::ucb::XContent;
+using ::com::sun::star::sdb::application::XDatabaseDocumentUI;
+
+namespace dbaccess
+{
+
+//============================================================
+//= ViewMonitor
+//============================================================
+
+bool ViewMonitor::onControllerConnected( const Reference< XController >& _rxController )
+{
+ bool bFirstControllerEver = ( m_bEverHadController == false );
+ m_bEverHadController = true;
+
+ m_xLastConnectedController = _rxController;
+ m_bLastIsFirstEverController = bFirstControllerEver;
+
+ return bFirstControllerEver;
+}
+
+bool ViewMonitor::onSetCurrentController( const Reference< XController >& _rxController )
+{
+ // we interpret this as "loading the document (including UI) is finished",
+ // if and only if this is the controller which was last connected, and it was the
+ // first controller ever connected
+ bool bLoadFinished = ( _rxController == m_xLastConnectedController ) && m_bLastIsFirstEverController;
+
+ // notify the respective events
+ if ( bLoadFinished )
+ m_rEventNotifier.notifyDocumentEventAsync( m_bIsNewDocument ? "OnNew" : "OnLoad" );
+
+ return bLoadFinished;
+}
+
+//============================================================
+//= ODatabaseDocument
+//============================================================
+DBG_NAME(ODatabaseDocument)
+
+extern "C" void SAL_CALL createRegistryInfo_ODatabaseDocument()
+{
+ static ::dba::OAutoRegistration< ODatabaseDocument > aAutoRegistration;
+}
+
+ODatabaseDocument::ODatabaseDocument(const ::rtl::Reference<ODatabaseModelImpl>& _pImpl )
+ :ModelDependentComponent( _pImpl )
+ ,ODatabaseDocument_OfficeDocument( getMutex() )
+ ,m_aModifyListeners( getMutex() )
+ ,m_aCloseListener( getMutex() )
+ ,m_aStorageListeners( getMutex() )
+ ,m_pEventContainer( new DocumentEvents( *this, getMutex(), _pImpl->getDocumentEvents() ) )
+ ,m_pEventExecutor( NULL ) // initialized below, ref-count-protected
+ ,m_aEventNotifier( *this, getMutex() )
+ ,m_aViewMonitor( m_aEventNotifier )
+ ,m_eInitState( NotInitialized )
+ ,m_bClosing( false )
+ ,m_bAllowDocumentScripting( false )
+ ,m_bHasBeenRecovered( false )
+{
+ DBG_CTOR(ODatabaseDocument,NULL);
+ OSL_TRACE( "DD: ctor: %p: %p", this, m_pImpl.get() );
+
+ osl_incrementInterlockedCount( &m_refCount );
+ {
+ impl_reparent_nothrow( m_xForms );
+ impl_reparent_nothrow( m_xReports );
+ impl_reparent_nothrow( m_pImpl->m_xTableDefinitions );
+ impl_reparent_nothrow( m_pImpl->m_xCommandDefinitions );
+
+ m_pEventExecutor = new DocumentEventExecutor( m_pImpl->m_aContext, this );
+ }
+ osl_decrementInterlockedCount( &m_refCount );
+
+ // if there previously was a document instance for the same Impl which was already initialized,
+ // then consider ourself initialized, too.
+ // #i94840#
+ if ( m_pImpl->hadInitializedDocument() )
+ {
+ // Note we set our init-state to "Initializing", not "Initialized". We're created from inside the ModelImpl,
+ // which is expected to call attachResource in case there was a previous incarnation of the document,
+ // so we can properly finish our initialization then.
+ impl_setInitializing();
+
+ if ( m_pImpl->getURL().getLength() )
+ {
+ // if the previous incarnation of the DatabaseDocument already had an URL, then creating this incarnation
+ // here is effectively loading the document.
+ // #i105505# / 2009-10-01 / frank.schoenheit@sun.com
+ m_aViewMonitor.onLoadedDocument();
+ }
+ }
+}
+
+ODatabaseDocument::~ODatabaseDocument()
+{
+ OSL_TRACE( "DD: dtor: %p: %p", this, m_pImpl.get() );
+ DBG_DTOR(ODatabaseDocument,NULL);
+ if ( !ODatabaseDocument_OfficeDocument::rBHelper.bInDispose && !ODatabaseDocument_OfficeDocument::rBHelper.bDisposed )
+ {
+ acquire();
+ dispose();
+ }
+
+ delete m_pEventContainer, m_pEventContainer = NULL;
+}
+
+Any SAL_CALL ODatabaseDocument::queryInterface( const Type& _rType ) throw (RuntimeException)
+{
+ // strip XEmbeddedScripts and XScriptInvocationContext if we have any form/report
+ // which already contains macros. In this case, the database document itself is not
+ // allowed to contain macros, too.
+ if ( !m_bAllowDocumentScripting
+ && ( _rType.equals( XEmbeddedScripts::static_type() )
+ || _rType.equals( XScriptInvocationContext::static_type() )
+ )
+ )
+ return Any();
+
+ Any aReturn = ODatabaseDocument_OfficeDocument::queryInterface(_rType);
+ if (!aReturn.hasValue())
+ aReturn = ODatabaseDocument_Title::queryInterface(_rType);
+ return aReturn;
+}
+
+void SAL_CALL ODatabaseDocument::acquire( ) throw ()
+{
+ ODatabaseDocument_OfficeDocument::acquire();
+}
+
+void SAL_CALL ODatabaseDocument::release( ) throw ()
+{
+ ODatabaseDocument_OfficeDocument::release();
+}
+
+Sequence< Type > SAL_CALL ODatabaseDocument::getTypes( ) throw (RuntimeException)
+{
+ Sequence< Type > aTypes = ::comphelper::concatSequences(
+ ODatabaseDocument_OfficeDocument::getTypes(),
+ ODatabaseDocument_Title::getTypes()
+ );
+
+ // strip XEmbeddedScripts and XScriptInvocationContext if we have any form/report
+ // which already contains macros. In this case, the database document itself is not
+ // allowed to contain macros, too.
+ if ( !m_bAllowDocumentScripting )
+ {
+ Sequence< Type > aStrippedTypes( aTypes.getLength() );
+ Type* pStripTo( aStrippedTypes.getArray() );
+
+ // strip XEmbeddedScripts, and immediately re-assign to aTypes
+ aTypes = Sequence< Type >(
+ pStripTo,
+ ::std::remove_copy_if(
+ aTypes.getConstArray(),
+ aTypes.getConstArray() + aTypes.getLength(),
+ pStripTo,
+ ::std::bind2nd( ::std::equal_to< Type >(), XEmbeddedScripts::static_type() )
+ ) - pStripTo
+ );
+
+ // strip XScriptInvocationContext, and immediately re-assign to aTypes
+ aTypes = Sequence< Type >(
+ pStripTo,
+ ::std::remove_copy_if(
+ aTypes.getConstArray(),
+ aTypes.getConstArray() + aTypes.getLength(),
+ pStripTo,
+ ::std::bind2nd( ::std::equal_to< Type >(), XScriptInvocationContext::static_type() )
+ ) - pStripTo
+ );
+ }
+
+ return aTypes;
+}
+
+Sequence< sal_Int8 > SAL_CALL ODatabaseDocument::getImplementationId( ) throw (RuntimeException)
+{
+ static ::cppu::OImplementationId * pId = 0;
+ if (! pId)
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if (! pId)
+ {
+ static ::cppu::OImplementationId aId;
+ pId = &aId;
+ }
+ }
+ return pId->getImplementationId();
+}
+
+// local functions
+namespace
+{
+ Reference< XStatusIndicator > lcl_extractStatusIndicator( const ::comphelper::NamedValueCollection& _rArguments )
+ {
+ Reference< XStatusIndicator > xStatusIndicator;
+ return _rArguments.getOrDefault( "StatusIndicator", xStatusIndicator );
+ }
+
+ static void lcl_triggerStatusIndicator_throw( const ::comphelper::NamedValueCollection& _rArguments, DocumentGuard& _rGuard, const bool _bStart )
+ {
+ Reference< XStatusIndicator > xStatusIndicator( lcl_extractStatusIndicator( _rArguments ) );
+ if ( !xStatusIndicator.is() )
+ return;
+
+ _rGuard.clear();
+ try
+ {
+ if ( _bStart )
+ xStatusIndicator->start( ::rtl::OUString(), (sal_Int32)1000000 );
+ else
+ xStatusIndicator->end();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ _rGuard.reset();
+ // note that |reset| can throw a DisposedException
+ }
+
+ static void lcl_extractStatusIndicator( const ::comphelper::NamedValueCollection& _rArguments, Sequence< Any >& _rCallArgs )
+ {
+ Reference< XStatusIndicator > xStatusIndicator( lcl_extractStatusIndicator( _rArguments ) );
+ if ( !xStatusIndicator.is() )
+ return;
+
+ sal_Int32 nLength = _rCallArgs.getLength();
+ _rCallArgs.realloc( nLength + 1 );
+ _rCallArgs[ nLength ] <<= xStatusIndicator;
+ }
+
+ static void lcl_extractAndStartStatusIndicator( const ::comphelper::NamedValueCollection& _rArguments, Reference< XStatusIndicator >& _rxStatusIndicator,
+ Sequence< Any >& _rCallArgs )
+ {
+ _rxStatusIndicator = lcl_extractStatusIndicator( _rArguments );
+ if ( !_rxStatusIndicator.is() )
+ return;
+
+ try
+ {
+ _rxStatusIndicator->start( ::rtl::OUString(), (sal_Int32)1000000 );
+
+ sal_Int32 nLength = _rCallArgs.getLength();
+ _rCallArgs.realloc( nLength + 1 );
+ _rCallArgs[ nLength ] <<= _rxStatusIndicator;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ static Sequence< PropertyValue > lcl_appendFileNameToDescriptor( const ::comphelper::NamedValueCollection& _rDescriptor, const ::rtl::OUString _rURL )
+ {
+ ::comphelper::NamedValueCollection aMutableDescriptor( _rDescriptor );
+ if ( _rURL.getLength() )
+ {
+ aMutableDescriptor.put( "FileName", _rURL );
+ aMutableDescriptor.put( "URL", _rURL );
+ }
+ return aMutableDescriptor.getPropertyValues();
+ }
+}
+
+void ODatabaseDocument::impl_setInitialized()
+{
+ m_eInitState = Initialized;
+
+ // start event notifications
+ m_aEventNotifier.onDocumentInitialized();
+}
+
+void ODatabaseDocument::impl_reset_nothrow()
+{
+ try
+ {
+ m_pImpl->clearConnections();
+ m_pImpl->disposeStorages();
+ m_pImpl->resetRootStroage();
+
+ clearObjectContainer( m_xForms );
+ clearObjectContainer( m_xReports );
+ clearObjectContainer( m_pImpl->m_xTableDefinitions );
+ clearObjectContainer( m_pImpl->m_xCommandDefinitions );
+
+ m_eInitState = NotInitialized;
+
+ m_pImpl->reset();
+ }
+ catch(const Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ m_pImpl->m_bDocumentReadOnly = sal_False;
+}
+
+void ODatabaseDocument::impl_import_nolck_throw( const ::comphelper::ComponentContext _rContext, const Reference< XInterface >& _rxTargetComponent,
+ const ::comphelper::NamedValueCollection& _rResource )
+{
+ Sequence< Any > aFilterCreationArgs;
+ Reference< XStatusIndicator > xStatusIndicator;
+ lcl_extractAndStartStatusIndicator( _rResource, xStatusIndicator, aFilterCreationArgs );
+
+ /** property map for import info set */
+ comphelper::PropertyMapEntry aExportInfoMap[] =
+ {
+ { MAP_LEN( "BaseURI"), 0,&::getCppuType( (::rtl::OUString *)0 ),beans::PropertyAttribute::MAYBEVOID, 0 },
+ { MAP_LEN( "StreamName"), 0,&::getCppuType( (::rtl::OUString *)0 ),beans::PropertyAttribute::MAYBEVOID, 0 },
+ { NULL, 0, 0, NULL, 0, 0 }
+ };
+ uno::Reference< beans::XPropertySet > xInfoSet( comphelper::GenericPropertySet_CreateInstance( new comphelper::PropertySetInfo( aExportInfoMap ) ) );
+ xInfoSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BaseURI")), uno::makeAny(_rResource.getOrDefault("URL",::rtl::OUString())));
+ xInfoSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StreamName")), uno::makeAny(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("content.xml"))));
+
+ const sal_Int32 nCount = aFilterCreationArgs.getLength();
+ aFilterCreationArgs.realloc(nCount + 1);
+ aFilterCreationArgs[nCount] <<= xInfoSet;
+
+ Reference< XImporter > xImporter(
+ _rContext.createComponentWithArguments( "com.sun.star.comp.sdb.DBFilter", aFilterCreationArgs ),
+ UNO_QUERY_THROW );
+
+ Reference< XComponent > xComponent( _rxTargetComponent, UNO_QUERY_THROW );
+ xImporter->setTargetDocument( xComponent );
+
+ Reference< XFilter > xFilter( xImporter, UNO_QUERY_THROW );
+ Sequence< PropertyValue > aFilterArgs( ODatabaseModelImpl::stripLoadArguments( _rResource ).getPropertyValues() );
+ xFilter->filter( aFilterArgs );
+
+ if ( xStatusIndicator.is() )
+ xStatusIndicator->end();
+}
+
+void SAL_CALL ODatabaseDocument::initNew( ) throw (DoubleInitializationException, IOException, Exception, RuntimeException)
+{
+ // SYNCHRONIZED ->
+ DocumentGuard aGuard( *this, DocumentGuard::InitMethod );
+
+ impl_reset_nothrow();
+
+ impl_setInitializing();
+
+ // create a temporary storage
+ Reference< XStorage > xTempStor( ::comphelper::OStorageHelper::GetTemporaryStorage(
+ m_pImpl->m_aContext.getLegacyServiceFactory() ) );
+
+ // store therein
+ impl_storeToStorage_throw( xTempStor, Sequence< PropertyValue >(), aGuard );
+
+ // let the impl know we're now based on this storage
+ m_pImpl->switchToStorage( xTempStor );
+
+ // for the newly created document, allow document-wide scripting
+ m_bAllowDocumentScripting = true;
+
+ impl_setInitialized();
+
+ m_aEventNotifier.notifyDocumentEventAsync( "OnTitleChanged" );
+
+ impl_setModified_nothrow( sal_False, aGuard );
+ // <- SYNCHRONIZED
+
+ m_aEventNotifier.notifyDocumentEvent( "OnCreate" );
+
+ impl_notifyStorageChange_nolck_nothrow( xTempStor );
+}
+
+void SAL_CALL ODatabaseDocument::load( const Sequence< PropertyValue >& _Arguments ) throw (DoubleInitializationException, IOException, Exception, RuntimeException)
+{
+ // SYNCHRONIZED ->
+ DocumentGuard aGuard( *this, DocumentGuard::InitMethod );
+
+ impl_reset_nothrow();
+
+ ::comphelper::NamedValueCollection aResource( _Arguments );
+ if ( aResource.has( "FileName" ) && !aResource.has( "URL" ) )
+ // FileName is the compatibility name for URL, so we might have clients passing
+ // a FileName only. However, some of our code works with the URL only, so ensure
+ // we have one.
+ aResource.put( "URL", aResource.get( "FileName" ) );
+ if ( aResource.has( "URL" ) && !aResource.has( "FileName" ) )
+ // similar ... just in case there is legacy code which expects a FileName only
+ aResource.put( "FileName", aResource.get( "URL" ) );
+
+ // now that somebody (perhaps) told us an macro execution mode, remember it as
+ // ImposedMacroExecMode
+ m_pImpl->setImposedMacroExecMode(
+ aResource.getOrDefault( "MacroExecutionMode", m_pImpl->getImposedMacroExecMode() ) );
+
+ impl_setInitializing();
+ try
+ {
+ aGuard.clear();
+ impl_import_nolck_throw( m_pImpl->m_aContext, *this, aResource );
+ aGuard.reset();
+ }
+ catch( const Exception& )
+ {
+ impl_reset_nothrow();
+ throw;
+ }
+ // tell our view monitor that the document has been loaded - this way it will fire the proper
+ // event (OnLoad instead of OnCreate) later on
+ m_aViewMonitor.onLoadedDocument();
+
+ // note that we do *not* call impl_setInitialized() here: The initialization is only complete
+ // when the XModel::attachResource has been called, not sooner.
+
+ impl_setModified_nothrow( sal_False, aGuard );
+ // <- SYNCHRONIZED
+}
+
+namespace
+{
+ bool lcl_hasAnyModifiedSubComponent_throw( const Reference< XController >& i_rController )
+ {
+ Reference< XDatabaseDocumentUI > xDatabaseUI( i_rController, UNO_QUERY_THROW );
+
+ Sequence< Reference< XComponent > > aComponents( xDatabaseUI->getSubComponents() );
+ const Reference< XComponent >* component = aComponents.getConstArray();
+ const Reference< XComponent >* componentsEnd = aComponents.getConstArray() + aComponents.getLength();
+
+ bool isAnyModified = false;
+ for ( ; component != componentsEnd; ++component )
+ {
+ Reference< XModifiable > xModify( *component, UNO_QUERY );
+ if ( xModify.is() )
+ {
+ isAnyModified = xModify->isModified();
+ continue;
+ }
+
+ // TODO: clarify: anything else to care for? Both the sub componbents with and without model
+ // should support the XModifiable interface, so I think nothing more is needed here.
+ OSL_ENSURE( false, "lcl_hasAnyModifiedSubComponent_throw: anything left to do here?" );
+ }
+
+ return isAnyModified;
+ }
+}
+
+::sal_Bool SAL_CALL ODatabaseDocument::wasModifiedSinceLastSave() throw ( RuntimeException )
+{
+ DocumentGuard aGuard( *this );
+
+ // The implementation here is somewhat sloppy, in that it returns whether *any* part of the whole
+ // database document, including opened sub components, is modified. This is more than what is requested:
+ // We need to return <TRUE/> if the doc itself, or any of the opened sub components, has been modified
+ // since the last call to any of the save* methods, or since the document has been loaded/created.
+ // However, the API definition explicitly allows to be that sloppy ...
+
+ if ( isModified() )
+ return sal_True;
+
+ // auto recovery is an "UI feature", it is to restore the UI the user knows. Thus,
+ // we ask our connected controllers, not simply our existing form/report definitions.
+ // (There is some information which even cannot be obtained without asking the controller.
+ // For instance, newly created, but not yet saved, forms/reports are acessible via the
+ // controller only, but not via the model.)
+
+ try
+ {
+ for ( Controllers::const_iterator ctrl = m_aControllers.begin();
+ ctrl != m_aControllers.end();
+ ++ctrl
+ )
+ {
+ if ( lcl_hasAnyModifiedSubComponent_throw( *ctrl ) )
+ return sal_True;
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ return sal_False;
+}
+
+void SAL_CALL ODatabaseDocument::storeToRecoveryFile( const ::rtl::OUString& i_TargetLocation, const Sequence< PropertyValue >& i_MediaDescriptor ) throw ( RuntimeException, IOException, WrappedTargetException )
+{
+ DocumentGuard aGuard( *this );
+ ModifyLock aLock( *this );
+
+ try
+ {
+ // create a storage for the target location
+ Reference< XStorage > xTargetStorage( impl_createStorageFor_throw( i_TargetLocation ) );
+
+ // first store the document as a whole into this storage
+ impl_storeToStorage_throw( xTargetStorage, i_MediaDescriptor, aGuard );
+
+ // save the sub components which need saving
+ DatabaseDocumentRecovery aDocRecovery( m_pImpl->m_aContext);
+ aDocRecovery.saveModifiedSubComponents( xTargetStorage, m_aControllers );
+
+ // commit the root storage
+ tools::stor::commitStorageIfWriteable( xTargetStorage );
+ }
+ catch( const Exception& )
+ {
+ Any aError = ::cppu::getCaughtException();
+ if ( aError.isExtractableTo( ::cppu::UnoType< IOException >::get() )
+ || aError.isExtractableTo( ::cppu::UnoType< RuntimeException >::get() )
+ || aError.isExtractableTo( ::cppu::UnoType< WrappedTargetException >::get() )
+ )
+ {
+ // allowed to leave
+ throw;
+ }
+
+ throw WrappedTargetException( ::rtl::OUString(), *this, aError );
+ }
+}
+
+void SAL_CALL ODatabaseDocument::recoverFromFile( const ::rtl::OUString& i_SourceLocation, const ::rtl::OUString& i_SalvagedFile, const Sequence< PropertyValue >& i_MediaDescriptor ) throw ( RuntimeException, IOException, WrappedTargetException )
+{
+ DocumentGuard aGuard( *this, DocumentGuard::InitMethod );
+
+ if ( i_SourceLocation.getLength() == 0 )
+ throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
+
+ try
+ {
+ // load the document itself, by simply delegating to our "load" method
+
+ // our load implementation expects the SalvagedFile and URL to be in the media descriptor
+ ::comphelper::NamedValueCollection aMediaDescriptor( i_MediaDescriptor );
+ aMediaDescriptor.put( "SalvagedFile", i_SalvagedFile );
+ aMediaDescriptor.put( "URL", i_SourceLocation );
+
+ aGuard.clear(); // (load has an own guarding scheme)
+ load( aMediaDescriptor.getPropertyValues() );
+
+ // Without a controller, we are unable to recover the sub components, as they're always tied to a controller.
+ // So, everything else is done when the first controller is connected.
+ m_bHasBeenRecovered = true;
+
+ // tell the impl that we've been loaded from the given location
+ m_pImpl->setDocFileLocation( i_SourceLocation );
+
+ // by definition (of XDocumentRecovery), we're responsible for delivering a fully-initialized document,
+ // which includes an attachResource call.
+ const ::rtl::OUString sLogicalDocumentURL( i_SalvagedFile.getLength() ? i_SalvagedFile : i_SourceLocation );
+ impl_attachResource( sLogicalDocumentURL, aMediaDescriptor.getPropertyValues(), aGuard );
+ // <- SYNCHRONIZED
+ }
+ catch( const Exception& )
+ {
+ Any aError = ::cppu::getCaughtException();
+ if ( aError.isExtractableTo( ::cppu::UnoType< IOException >::get() )
+ || aError.isExtractableTo( ::cppu::UnoType< RuntimeException >::get() )
+ || aError.isExtractableTo( ::cppu::UnoType< WrappedTargetException >::get() )
+ )
+ {
+ // allowed to leave
+ throw;
+ }
+
+ throw WrappedTargetException( ::rtl::OUString(), *this, aError );
+ }
+}
+
+// XModel
+sal_Bool SAL_CALL ODatabaseDocument::attachResource( const ::rtl::OUString& _rURL, const Sequence< PropertyValue >& _rArguments ) throw (RuntimeException)
+{
+ DocumentGuard aGuard( *this, DocumentGuard::MethodUsedDuringInit );
+ return impl_attachResource( _rURL, _rArguments, aGuard );
+}
+
+sal_Bool ODatabaseDocument::impl_attachResource( const ::rtl::OUString& i_rLogicalDocumentURL,
+ const Sequence< PropertyValue >& i_rMediaDescriptor, DocumentGuard& _rDocGuard )
+{
+ if ( ( i_rLogicalDocumentURL == getURL() )
+ && ( i_rMediaDescriptor.getLength() == 1 )
+ && ( i_rMediaDescriptor[0].Name.compareToAscii( "BreakMacroSignature" ) == 0 )
+ )
+ {
+ // this is a BAD hack of the Basic importer code ... there should be a dedicated API for this,
+ // not this bad mis-using of existing interfaces
+ return sal_False;
+ // (we do not support macro signatures, so we can ignore this call)
+ }
+
+ // if no URL has been provided, the caller was lazy enough to not call our getURL - which is not allowed anymore,
+ // now since getURL and getLocation both return the same, so calling one of those should be simple.
+ ::rtl::OUString sDocumentURL( i_rLogicalDocumentURL );
+ OSL_ENSURE( sDocumentURL.getLength(), "ODatabaseDocument::impl_attachResource: invalid URL!" );
+ if ( !sDocumentURL.getLength() )
+ sDocumentURL = getURL();
+
+ m_pImpl->setResource( sDocumentURL, i_rMediaDescriptor );
+
+ if ( impl_isInitializing() )
+ { // this means we've just been loaded, and this is the attachResource call which follows
+ // the load call.
+ impl_setInitialized();
+
+ // determine whether the document as a whole, or sub documents, have macros. Especially the latter
+ // controls the availability of our XEmbeddedScripts and XScriptInvocationContext interfaces, and we
+ // should know this before anybody actually uses the object.
+ m_bAllowDocumentScripting = ( m_pImpl->determineEmbeddedMacros() != ODatabaseModelImpl::eSubDocumentMacros );
+
+ _rDocGuard.clear();
+ // <- SYNCHRONIZED
+ m_aEventNotifier.notifyDocumentEvent( "OnLoadFinished" );
+ }
+
+ return sal_True;
+}
+
+::rtl::OUString SAL_CALL ODatabaseDocument::getURL( ) throw (RuntimeException)
+{
+ DocumentGuard aGuard( *this, DocumentGuard::MethodWithoutInit );
+ return m_pImpl->getURL();
+}
+
+Sequence< PropertyValue > SAL_CALL ODatabaseDocument::getArgs( ) throw (RuntimeException)
+{
+ DocumentGuard aGuard( *this, DocumentGuard::MethodWithoutInit );
+ return m_pImpl->getMediaDescriptor().getPropertyValues();
+}
+
+void SAL_CALL ODatabaseDocument::connectController( const Reference< XController >& _xController ) throw (RuntimeException)
+{
+ DocumentGuard aGuard( *this );
+
+#if OSL_DEBUG_LEVEL > 0
+ for ( Controllers::const_iterator controller = m_aControllers.begin();
+ controller != m_aControllers.end();
+ ++controller
+ )
+ {
+ OSL_ENSURE( *controller != _xController, "ODatabaseDocument::connectController: this controller is already connected!" );
+ }
+#endif
+
+ m_aControllers.push_back( _xController );
+
+ m_aEventNotifier.notifyDocumentEventAsync( "OnViewCreated", Reference< XController2 >( _xController, UNO_QUERY ) );
+
+ bool bFirstControllerEver = m_aViewMonitor.onControllerConnected( _xController );
+ if ( !bFirstControllerEver )
+ return;
+
+ // check/adjust our macro mode.
+ m_pImpl->checkMacrosOnLoading();
+}
+
+void SAL_CALL ODatabaseDocument::disconnectController( const Reference< XController >& _xController ) throw (RuntimeException)
+{
+ bool bNotifyViewClosed = false;
+ bool bLastControllerGone = false;
+ bool bIsClosing = false;
+
+ // SYNCHRONIZED ->
+ {
+ DocumentGuard aGuard( *this );
+
+ Controllers::iterator pos = ::std::find( m_aControllers.begin(), m_aControllers.end(), _xController );
+ OSL_ENSURE( pos != m_aControllers.end(), "ODatabaseDocument::disconnectController: don't know this controller!" );
+ if ( pos != m_aControllers.end() )
+ {
+ m_aControllers.erase( pos );
+ bNotifyViewClosed = true;
+ }
+
+ if ( m_xCurrentController == _xController )
+ m_xCurrentController = NULL;
+
+ bLastControllerGone = m_aControllers.empty();
+ bIsClosing = m_bClosing;
+ }
+ // <- SYNCHRONIZED
+
+ if ( bNotifyViewClosed )
+ m_aEventNotifier.notifyDocumentEvent( "OnViewClosed", Reference< XController2 >( _xController, UNO_QUERY ) );
+
+ if ( bLastControllerGone && !bIsClosing )
+ {
+ // if this was the last view, close the document as a whole
+ // #i51157# / 2006-03-16 / frank.schoenheit@sun.com
+ try
+ {
+ close( sal_True );
+ }
+ catch( const CloseVetoException& )
+ {
+ // okay, somebody vetoed and took ownership
+ }
+ }
+}
+
+void SAL_CALL ODatabaseDocument::lockControllers( ) throw (RuntimeException)
+{
+ DocumentGuard aGuard( *this );
+
+ ++m_pImpl->m_nControllerLockCount;
+}
+
+void SAL_CALL ODatabaseDocument::unlockControllers( ) throw (RuntimeException)
+{
+ DocumentGuard aGuard( *this );
+
+ --m_pImpl->m_nControllerLockCount;
+}
+
+sal_Bool SAL_CALL ODatabaseDocument::hasControllersLocked( ) throw (RuntimeException)
+{
+ DocumentGuard aGuard( *this );
+
+ return m_pImpl->m_nControllerLockCount != 0;
+}
+
+Reference< XController > SAL_CALL ODatabaseDocument::getCurrentController() throw (RuntimeException)
+{
+ DocumentGuard aGuard( *this );
+
+ return m_xCurrentController.is() ? m_xCurrentController : ( m_aControllers.empty() ? Reference< XController >() : *m_aControllers.begin() );
+}
+
+void SAL_CALL ODatabaseDocument::setCurrentController( const Reference< XController >& _xController ) throw (NoSuchElementException, RuntimeException)
+{
+ DocumentGuard aGuard( *this );
+
+ m_xCurrentController = _xController;
+
+ if ( !m_aViewMonitor.onSetCurrentController( _xController ) )
+ return;
+
+ // check if there are sub components to recover from our document storage
+ bool bAttemptRecovery = m_bHasBeenRecovered;
+ if ( !bAttemptRecovery && m_pImpl->getMediaDescriptor().has( "ForceRecovery" ) )
+ // do not use getOrDefault, it will throw for invalid types, which is not desired here
+ m_pImpl->getMediaDescriptor().get( "ForceRecovery" ) >>= bAttemptRecovery;
+
+ if ( !bAttemptRecovery )
+ return;
+
+ try
+ {
+ DatabaseDocumentRecovery aDocRecovery( m_pImpl->m_aContext );
+ aDocRecovery.recoverSubDocuments( m_pImpl->getRootStorage(), _xController );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+}
+
+Reference< XInterface > SAL_CALL ODatabaseDocument::getCurrentSelection( ) throw (RuntimeException)
+{
+ DocumentGuard aGuard( *this );
+
+ Reference< XInterface > xRet;
+ Reference< XSelectionSupplier > xDocView( getCurrentController(), UNO_QUERY );
+ if ( xDocView.is() )
+ xRet.set(xDocView->getSelection(),UNO_QUERY);
+
+ return xRet;
+}
+
+// XStorable
+sal_Bool SAL_CALL ODatabaseDocument::hasLocation( ) throw (RuntimeException)
+{
+ return getLocation().getLength() > 0;
+}
+
+::rtl::OUString SAL_CALL ODatabaseDocument::getLocation( ) throw (RuntimeException)
+{
+ DocumentGuard aGuard( *this, DocumentGuard::MethodWithoutInit );
+ return m_pImpl->getURL();
+ // both XStorable::getLocation and XModel::getURL have to return the URL of the document, *not*
+ // the location of the file which the docunment was possibly recovered from (which would be getDocFileLocation)
+}
+
+sal_Bool SAL_CALL ODatabaseDocument::isReadonly( ) throw (RuntimeException)
+{
+ DocumentGuard aGuard( *this, DocumentGuard::MethodWithoutInit );
+ return m_pImpl->m_bDocumentReadOnly;
+}
+
+void SAL_CALL ODatabaseDocument::store( ) throw (IOException, RuntimeException)
+{
+ DocumentGuard aGuard( *this );
+
+ ::rtl::OUString sDocumentURL( m_pImpl->getURL() );
+ if ( sDocumentURL.getLength() )
+ {
+ if ( m_pImpl->getDocFileLocation() == m_pImpl->getURL() )
+ if ( m_pImpl->m_bDocumentReadOnly )
+ throw IOException();
+
+ impl_storeAs_throw( m_pImpl->getURL(), m_pImpl->getMediaDescriptor(), SAVE, aGuard );
+ return;
+ }
+
+ // if we have no URL, but did survive the DocumentGuard above, then we've been inited via XLoadable::initNew,
+ // i.e. we're based on a temporary storage
+ OSL_ENSURE( m_pImpl->getDocFileLocation().getLength() == 0, "ODatabaseDocument::store: unexpected URL inconsistency!" );
+
+ try
+ {
+ impl_storeToStorage_throw( m_pImpl->getRootStorage(), m_pImpl->getMediaDescriptor().getPropertyValues(), aGuard );
+ }
+ catch( const Exception& )
+ {
+ Any aError = ::cppu::getCaughtException();
+ if ( aError.isExtractableTo( ::cppu::UnoType< IOException >::get() )
+ || aError.isExtractableTo( ::cppu::UnoType< RuntimeException >::get() )
+ )
+ {
+ // allowed to leave
+ throw;
+ }
+ impl_throwIOExceptionCausedBySave_throw( aError, ::rtl::OUString() );
+ }
+}
+
+void ODatabaseDocument::impl_throwIOExceptionCausedBySave_throw( const Any& i_rError, const ::rtl::OUString& i_rTargetURL ) const
+{
+ ::rtl::OUString sErrorMessage = extractExceptionMessage( m_pImpl->m_aContext, i_rError );
+ sErrorMessage = ResourceManager::loadString(
+ RID_STR_ERROR_WHILE_SAVING,
+ "$location$", i_rTargetURL,
+ "$message$", sErrorMessage
+ );
+ throw IOException( sErrorMessage, *const_cast< ODatabaseDocument* >( this ) );
+}
+
+void ODatabaseDocument::impl_storeAs_throw( const ::rtl::OUString& _rURL, const ::comphelper::NamedValueCollection& _rArguments,
+ const StoreType _eType, DocumentGuard& _rGuard ) throw ( IOException, RuntimeException )
+{
+ OSL_PRECOND( ( _eType == SAVE ) || ( _eType == SAVE_AS ),
+ "ODatabaseDocument::impl_storeAs_throw: you introduced a new type which cannot be handled here!" );
+
+ // if we're in the process of initializing the document (which effectively means it is an implicit
+ // initialization triggered in storeAsURL), the we do not notify events, since to an observer, the SaveAs
+ // should not be noticable
+ bool bIsInitializationProcess = impl_isInitializing();
+
+ if ( !bIsInitializationProcess )
+ {
+ _rGuard.clear();
+ m_aEventNotifier.notifyDocumentEvent( _eType == SAVE ? "OnSave" : "OnSaveAs", NULL, makeAny( _rURL ) );
+ _rGuard.reset();
+ }
+
+ Reference< XStorage > xNewRootStorage;
+ // will be non-NULL if our storage changed
+
+ try
+ {
+ ModifyLock aLock( *this );
+ // ignore all changes of our "modified" state during storing
+
+ sal_Bool bLocationChanged = ( _rURL != m_pImpl->getDocFileLocation() );
+ if ( bLocationChanged )
+ {
+ // create storage for target URL
+ Reference< XStorage > xTargetStorage( impl_createStorageFor_throw( _rURL ) );
+
+ if ( m_pImpl->isEmbeddedDatabase() )
+ m_pImpl->clearConnections();
+
+ // commit everything
+ m_pImpl->commitEmbeddedStorage();
+ m_pImpl->commitStorages();
+
+ // copy own storage to target storage
+ Reference< XStorage > xCurrentStorage( m_pImpl->getRootStorage() );
+ if ( xCurrentStorage.is() )
+ xCurrentStorage->copyToStorage( xTargetStorage );
+
+ m_pImpl->disposeStorages();
+
+ // each and every document definition obtained via m_xForms and m_xReports depends
+ // on the sub storages which we just disposed. So, dispose the forms/reports collections, too.
+ // This ensures that they're re-created when needed.
+ clearObjectContainer( m_xForms );
+ clearObjectContainer( m_xReports );
+
+ xNewRootStorage = m_pImpl->switchToStorage( xTargetStorage );
+
+ m_pImpl->m_bDocumentReadOnly = sal_False;
+ }
+
+ // store to current storage
+ Reference< XStorage > xCurrentStorage( m_pImpl->getOrCreateRootStorage(), UNO_QUERY_THROW );
+ Sequence< PropertyValue > aMediaDescriptor( lcl_appendFileNameToDescriptor( _rArguments, _rURL ) );
+ impl_storeToStorage_throw( xCurrentStorage, aMediaDescriptor, _rGuard );
+
+ // success - tell our impl
+ m_pImpl->setDocFileLocation( _rURL );
+ m_pImpl->setResource( _rURL, aMediaDescriptor );
+
+ // if we are in an initialization process, then this is finished, now that we stored the document
+ if ( bIsInitializationProcess )
+ impl_setInitialized();
+ }
+ catch( const Exception& )
+ {
+ Any aError = ::cppu::getCaughtException();
+
+ // notify the failure
+ if ( !bIsInitializationProcess )
+ m_aEventNotifier.notifyDocumentEventAsync( _eType == SAVE ? "OnSaveFailed" : "OnSaveAsFailed", NULL, makeAny( _rURL ) );
+
+ if ( aError.isExtractableTo( ::cppu::UnoType< IOException >::get() )
+ || aError.isExtractableTo( ::cppu::UnoType< RuntimeException >::get() )
+ )
+ {
+ // allowed to leave
+ throw;
+ }
+
+ impl_throwIOExceptionCausedBySave_throw( aError, _rURL );
+ }
+
+ // notify the document event
+ if ( !bIsInitializationProcess )
+ m_aEventNotifier.notifyDocumentEventAsync( _eType == SAVE ? "OnSaveDone" : "OnSaveAsDone", NULL, makeAny( _rURL ) );
+
+ // reset our "modified" flag, and clear the guard
+ impl_setModified_nothrow( sal_False, _rGuard );
+ // <- SYNCHRONIZED
+
+ // notify storage listeners
+ if ( xNewRootStorage.is() )
+ impl_notifyStorageChange_nolck_nothrow( xNewRootStorage );
+}
+
+Reference< XStorage > ODatabaseDocument::impl_createStorageFor_throw( const ::rtl::OUString& _rURL ) const
+{
+ Reference < ::com::sun::star::ucb::XSimpleFileAccess > xTempAccess;
+ m_pImpl->m_aContext.createComponent( ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ,xTempAccess);
+ Reference< io::XStream > xStream = xTempAccess->openFileReadWrite( _rURL );
+ Reference< io::XTruncate > xTruncate(xStream,UNO_QUERY);
+ if ( xTruncate.is() )
+ {
+ xTruncate->truncate();
+ }
+ Sequence<Any> aParam(2);
+ aParam[0] <<= xStream;
+ aParam[1] <<= ElementModes::READWRITE | ElementModes::TRUNCATE;
+
+ Reference< XSingleServiceFactory > xStorageFactory( m_pImpl->createStorageFactory(), UNO_SET_THROW );
+ return Reference< XStorage >( xStorageFactory->createInstanceWithArguments( aParam ), UNO_QUERY_THROW );
+}
+
+void SAL_CALL ODatabaseDocument::storeAsURL( const ::rtl::OUString& _rURL, const Sequence< PropertyValue >& _rArguments ) throw (IOException, RuntimeException)
+{
+ // SYNCHRONIZED ->
+ DocumentGuard aGuard( *this, DocumentGuard::MethodWithoutInit );
+
+ // Normally, a document initialization is done via XLoadable::load or XLoadable::initNew. For convenience
+ // reasons, and to not break existing API clients, it's allowed to call storeAsURL without having initialized
+ // the document, in which case the initialization will be done implicitly.
+ bool bImplicitInitialization = !impl_isInitialized();
+ // implicit initialization while another initialization is just running is not possible
+ if ( bImplicitInitialization && impl_isInitializing() )
+ throw DoubleInitializationException();
+
+ if ( bImplicitInitialization )
+ impl_setInitializing();
+
+ try
+ {
+ impl_storeAs_throw( _rURL, _rArguments, SAVE_AS, aGuard );
+ // <- SYNCHRONIZED
+
+ // impl_storeAs_throw cleared the lock on our mutex, but the below lines need this lock
+ // SYNCHRONIZED ->
+ aGuard.reset();
+
+ // our title might have changed, potentially at least
+ // Sadly, we cannot check this: Calling getTitle here and now would not deliver
+ // an up-to-date result, as the call is delegated to our TitleHelper instance, which itself
+ // updates its title only if it gets the OnSaveAsDone event (which was sent asynchronously
+ // by impl_storeAs_throw). So, we simply notify always, and also asynchronously
+ m_aEventNotifier.notifyDocumentEventAsync( "OnTitleChanged" );
+ }
+ catch( const Exception& )
+ {
+ impl_reset_nothrow();
+ throw;
+ }
+
+ if ( bImplicitInitialization )
+ m_bAllowDocumentScripting = true;
+
+ aGuard.clear();
+ // <- SYNCHRONIZED
+
+ if ( bImplicitInitialization )
+ m_aEventNotifier.notifyDocumentEvent( "OnCreate" );
+}
+
+void ODatabaseDocument::impl_storeToStorage_throw( const Reference< XStorage >& _rxTargetStorage, const Sequence< PropertyValue >& _rMediaDescriptor,
+ DocumentGuard& _rDocGuard ) const
+{
+ if ( !_rxTargetStorage.is() )
+ throw IllegalArgumentException( ::rtl::OUString(), *const_cast< ODatabaseDocument* >( this ), 1 );
+
+ if ( !m_pImpl.is() )
+ throw DisposedException( ::rtl::OUString(), *const_cast< ODatabaseDocument* >( this ) );
+
+ try
+ {
+ // commit everything
+ m_pImpl->commitEmbeddedStorage();
+ m_pImpl->commitStorages();
+
+ // copy own storage to target storage
+ if ( impl_isInitialized() )
+ {
+ Reference< XStorage > xCurrentStorage( m_pImpl->getOrCreateRootStorage(), UNO_QUERY_THROW );
+ if ( xCurrentStorage != _rxTargetStorage )
+ xCurrentStorage->copyToStorage( _rxTargetStorage );
+ }
+
+ // write into target storage
+ ::comphelper::NamedValueCollection aWriteArgs( _rMediaDescriptor );
+ lcl_triggerStatusIndicator_throw( aWriteArgs, _rDocGuard, true );
+ impl_writeStorage_throw( _rxTargetStorage, aWriteArgs );
+ lcl_triggerStatusIndicator_throw( aWriteArgs, _rDocGuard, false );
+
+ // commit target storage
+ OSL_VERIFY( tools::stor::commitStorageIfWriteable( _rxTargetStorage ) );
+ }
+ catch( const IOException& ) { throw; }
+ catch( const RuntimeException& ) { throw; }
+ catch ( const Exception& e )
+ {
+ throw IOException( e.Message, *const_cast< ODatabaseDocument* >( this ) );
+ }
+}
+
+void SAL_CALL ODatabaseDocument::storeToURL( const ::rtl::OUString& _rURL, const Sequence< PropertyValue >& _rArguments ) throw (IOException, RuntimeException)
+{
+ DocumentGuard aGuard( *this );
+ ModifyLock aLock( *this );
+
+ {
+ aGuard.clear();
+ m_aEventNotifier.notifyDocumentEvent( "OnSaveTo", NULL, makeAny( _rURL ) );
+ aGuard.reset();
+ }
+
+ try
+ {
+ // create storage for target URL
+ Reference< XStorage > xTargetStorage( impl_createStorageFor_throw( _rURL ) );
+
+ // extend media descriptor with URL
+ Sequence< PropertyValue > aMediaDescriptor( lcl_appendFileNameToDescriptor( _rArguments, _rURL ) );
+
+ // store to this storage
+ impl_storeToStorage_throw( xTargetStorage, aMediaDescriptor, aGuard );
+ }
+ catch( const Exception& )
+ {
+ Any aError = ::cppu::getCaughtException();
+ m_aEventNotifier.notifyDocumentEventAsync( "OnSaveToFailed", NULL, aError );
+
+ if ( aError.isExtractableTo( ::cppu::UnoType< IOException >::get() )
+ || aError.isExtractableTo( ::cppu::UnoType< RuntimeException >::get() )
+ )
+ {
+ // allowed to leave
+ throw;
+ }
+
+ impl_throwIOExceptionCausedBySave_throw( aError, _rURL );
+ }
+
+ m_aEventNotifier.notifyDocumentEventAsync( "OnSaveToDone", NULL, makeAny( _rURL ) );
+}
+
+// XModifyBroadcaster
+void SAL_CALL ODatabaseDocument::addModifyListener( const Reference< XModifyListener >& _xListener ) throw (RuntimeException)
+{
+ DocumentGuard aGuard( *this );
+ m_aModifyListeners.addInterface(_xListener);
+}
+
+void SAL_CALL ODatabaseDocument::removeModifyListener( const Reference< XModifyListener >& _xListener ) throw (RuntimeException)
+{
+ DocumentGuard aGuard( *this );
+ m_aModifyListeners.removeInterface(_xListener);
+}
+
+// XModifiable
+sal_Bool SAL_CALL ODatabaseDocument::isModified( ) throw (RuntimeException)
+{
+ DocumentGuard aGuard( *this );
+
+ return m_pImpl->m_bModified;
+}
+
+void SAL_CALL ODatabaseDocument::setModified( sal_Bool _bModified ) throw (PropertyVetoException, RuntimeException)
+{
+ DocumentGuard aGuard( *this, DocumentGuard::MethodWithoutInit );
+ if ( impl_isInitialized() )
+ impl_setModified_nothrow( _bModified, aGuard );
+ // it's allowed to call setModified without the document being initialized already. In this case,
+ // we simply ignore the call - when the initialization is finished, the respective code will set
+ // a proper "modified" flag
+}
+
+void ODatabaseDocument::impl_setModified_nothrow( sal_Bool _bModified, DocumentGuard& _rGuard )
+{
+ // SYNCHRONIZED ->
+ bool bModifiedChanged = ( m_pImpl->m_bModified != _bModified ) && ( !m_pImpl->isModifyLocked() );
+
+ if ( bModifiedChanged )
+ {
+ m_pImpl->m_bModified = _bModified;
+ m_aEventNotifier.notifyDocumentEventAsync( "OnModifyChanged" );
+ }
+ _rGuard.clear();
+ // <- SYNCHRONIZED
+
+ if ( bModifiedChanged )
+ {
+ lang::EventObject aEvent( *this );
+ m_aModifyListeners.notifyEach( &XModifyListener::modified, aEvent );
+ }
+}
+
+// ::com::sun::star::document::XEventBroadcaster
+void SAL_CALL ODatabaseDocument::addEventListener(const uno::Reference< document::XEventListener >& _Listener ) throw (uno::RuntimeException)
+{
+ m_aEventNotifier.addLegacyEventListener( _Listener );
+}
+
+void SAL_CALL ODatabaseDocument::removeEventListener( const uno::Reference< document::XEventListener >& _Listener ) throw (uno::RuntimeException)
+{
+ m_aEventNotifier.removeLegacyEventListener( _Listener );
+}
+
+void SAL_CALL ODatabaseDocument::addDocumentEventListener( const Reference< XDocumentEventListener >& _Listener ) throw (RuntimeException)
+{
+ m_aEventNotifier.addDocumentEventListener( _Listener );
+}
+
+void SAL_CALL ODatabaseDocument::removeDocumentEventListener( const Reference< XDocumentEventListener >& _Listener ) throw (RuntimeException)
+{
+ m_aEventNotifier.removeDocumentEventListener( _Listener );
+}
+
+void SAL_CALL ODatabaseDocument::notifyDocumentEvent( const ::rtl::OUString& _EventName, const Reference< XController2 >& _ViewController, const Any& _Supplement ) throw (IllegalArgumentException, NoSupportException, RuntimeException)
+{
+ if ( !_EventName.getLength() )
+ throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
+
+ // SYNCHRONIZED ->
+ DocumentGuard aGuard( *this );
+
+ if ( !DocumentEvents::needsSynchronousNotification( _EventName ) )
+ {
+ m_aEventNotifier.notifyDocumentEventAsync( _EventName, _ViewController, _Supplement );
+ return;
+ }
+ aGuard.clear();
+ // <- SYNCHRONIZED
+
+ m_aEventNotifier.notifyDocumentEvent( _EventName, _ViewController, _Supplement );
+}
+
+Sequence< PropertyValue > SAL_CALL ODatabaseDocument::getPrinter( ) throw (RuntimeException)
+{
+ DBG_ERROR( "ODatabaseDocument::getPrinter: not supported!" );
+ return Sequence< PropertyValue >();
+}
+
+void SAL_CALL ODatabaseDocument::setPrinter( const Sequence< PropertyValue >& /*aPrinter*/ ) throw (IllegalArgumentException, RuntimeException)
+{
+ DBG_ERROR( "ODatabaseDocument::setPrinter: not supported!" );
+}
+
+void SAL_CALL ODatabaseDocument::print( const Sequence< PropertyValue >& /*xOptions*/ ) throw (IllegalArgumentException, RuntimeException)
+{
+ DBG_ERROR( "ODatabaseDocument::print: not supported!" );
+}
+
+void ODatabaseDocument::impl_reparent_nothrow( const WeakReference< XNameAccess >& _rxContainer )
+{
+ Reference< XChild > xChild( _rxContainer.get(), UNO_QUERY );
+ if ( xChild.is() )
+ xChild->setParent( *this );
+}
+
+void ODatabaseDocument::clearObjectContainer( WeakReference< XNameAccess >& _rxContainer)
+{
+ Reference< XNameAccess > xContainer = _rxContainer;
+ ::comphelper::disposeComponent( xContainer );
+
+ Reference< XChild > xChild( _rxContainer.get(),UNO_QUERY );
+ if ( xChild.is() )
+ xChild->setParent( NULL );
+ _rxContainer = Reference< XNameAccess >();
+}
+
+Reference< XNameAccess > ODatabaseDocument::impl_getDocumentContainer_throw( ODatabaseModelImpl::ObjectType _eType )
+{
+ if ( ( _eType != ODatabaseModelImpl::E_FORM ) && ( _eType != ODatabaseModelImpl::E_REPORT ) )
+ throw IllegalArgumentException();
+
+ bool bFormsContainer = _eType == ODatabaseModelImpl::E_FORM;
+
+ WeakReference< XNameAccess >& rContainerRef( bFormsContainer ? m_xForms : m_xReports );
+ Reference< XNameAccess > xContainer = rContainerRef;
+ if ( !xContainer.is() )
+ {
+ Any aValue;
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xMy(*this);
+ if ( dbtools::getDataSourceSetting(xMy,bFormsContainer ? "Forms" : "Reports",aValue) )
+ {
+ ::rtl::OUString sSupportService;
+ aValue >>= sSupportService;
+ if ( sSupportService.getLength() )
+ {
+ Sequence<Any> aArgs(1);
+ aArgs[0] <<= NamedValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DatabaseDocument")),makeAny(xMy));
+ xContainer.set(m_pImpl->m_aContext.createComponentWithArguments(sSupportService,aArgs),UNO_QUERY);
+ rContainerRef = xContainer;
+ }
+ }
+ if ( !xContainer.is() )
+ {
+ TContentPtr& rContainerData( m_pImpl->getObjectContainer( _eType ) );
+ rContainerRef = xContainer = new ODocumentContainer( m_pImpl->m_aContext.getLegacyServiceFactory(), *this, rContainerData, bFormsContainer );
+ }
+ impl_reparent_nothrow( xContainer );
+ }
+ return xContainer;
+}
+
+void ODatabaseDocument::impl_closeControllerFrames_nolck_throw( sal_Bool _bDeliverOwnership )
+{
+ Controllers aCopy = m_aControllers;
+
+ Controllers::iterator aEnd = aCopy.end();
+ for ( Controllers::iterator aIter = aCopy.begin(); aIter != aEnd ; ++aIter )
+ {
+ if ( !aIter->is() )
+ continue;
+
+ try
+ {
+ Reference< XCloseable> xFrame( (*aIter)->getFrame(), UNO_QUERY );
+ if ( xFrame.is() )
+ xFrame->close( _bDeliverOwnership );
+ }
+ catch( const CloseVetoException& ) { throw; }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+}
+
+struct DisposeControllerFrame : public ::std::unary_function< Reference< XController >, void >
+{
+ void operator()( const Reference< XController >& _rxController ) const
+ {
+ try
+ {
+ if ( !_rxController.is() )
+ return;
+
+ Reference< XFrame > xFrame( _rxController->getFrame() );
+ ::comphelper::disposeComponent( xFrame );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ };
+};
+
+void ODatabaseDocument::impl_disposeControllerFrames_nothrow()
+{
+ Controllers aCopy;
+ aCopy.swap( m_aControllers ); // ensure m_aControllers is empty afterwards
+ ::std::for_each( aCopy.begin(), aCopy.end(), DisposeControllerFrame() );
+}
+
+void SAL_CALL ODatabaseDocument::close( sal_Bool _bDeliverOwnership ) throw (CloseVetoException, RuntimeException)
+{
+ // nearly everything below can/must be done without our mutex locked, the below is just for
+ // the checks for being disposed and the like
+ // SYNCHRONIZED ->
+ {
+ DocumentGuard aGuard( *this );
+ m_bClosing = true;
+ }
+ // <- SYNCHRONIZED
+
+ try
+ {
+ // allow listeners to veto
+ lang::EventObject aEvent( *this );
+ m_aCloseListener.forEach< XCloseListener >(
+ boost::bind( &XCloseListener::queryClosing, _1, boost::cref( aEvent ), boost::cref( _bDeliverOwnership ) ) );
+
+ // notify that we're going to unload
+ m_aEventNotifier.notifyDocumentEvent( "OnPrepareUnload" );
+
+ impl_closeControllerFrames_nolck_throw( _bDeliverOwnership );
+
+ m_aCloseListener.notifyEach( &XCloseListener::notifyClosing, (const lang::EventObject&)aEvent );
+
+ dispose();
+ }
+ catch ( const Exception& )
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ m_bClosing = false;
+ throw;
+ }
+
+ // SYNCHRONIZED ->
+ ::osl::MutexGuard aGuard( m_aMutex );
+ m_bClosing = false;
+ // <- SYNCHRONIZED
+}
+
+void SAL_CALL ODatabaseDocument::addCloseListener( const Reference< ::com::sun::star::util::XCloseListener >& Listener ) throw (RuntimeException)
+{
+ DocumentGuard aGuard( *this );
+ m_aCloseListener.addInterface(Listener);
+}
+
+void SAL_CALL ODatabaseDocument::removeCloseListener( const Reference< ::com::sun::star::util::XCloseListener >& Listener ) throw (RuntimeException)
+{
+ DocumentGuard aGuard( *this );
+ m_aCloseListener.removeInterface(Listener);
+}
+
+Reference< XNameAccess > SAL_CALL ODatabaseDocument::getFormDocuments( ) throw (RuntimeException)
+{
+ DocumentGuard aGuard( *this, DocumentGuard::MethodUsedDuringInit );
+ return impl_getDocumentContainer_throw( ODatabaseModelImpl::E_FORM );
+}
+
+Reference< XNameAccess > SAL_CALL ODatabaseDocument::getReportDocuments( ) throw (RuntimeException)
+{
+ DocumentGuard aGuard( *this, DocumentGuard::MethodUsedDuringInit );
+ return impl_getDocumentContainer_throw( ODatabaseModelImpl::E_REPORT );
+}
+
+void ODatabaseDocument::WriteThroughComponent( const Reference< XComponent >& xComponent, const sal_Char* pStreamName,
+ const sal_Char* pServiceName, const Sequence< Any >& _rArguments, const Sequence< PropertyValue >& rMediaDesc,
+ const Reference<XStorage>& _xStorageToSaveTo ) const
+{
+ OSL_ENSURE( pStreamName, "Need stream name!" );
+ OSL_ENSURE( pServiceName, "Need service name!" );
+
+ // open stream
+ ::rtl::OUString sStreamName = ::rtl::OUString::createFromAscii( pStreamName );
+ Reference< XStream > xStream = _xStorageToSaveTo->openStreamElement( sStreamName, ElementModes::READWRITE | ElementModes::TRUNCATE );
+ if ( !xStream.is() )
+ return;
+
+ Reference< XOutputStream > xOutputStream( xStream->getOutputStream() );
+ OSL_ENSURE( xOutputStream.is(), "Can't create output stream in package!" );
+ if ( !xOutputStream.is() )
+ return;
+
+ Reference< XSeekable > xSeek( xOutputStream, UNO_QUERY );
+ if ( xSeek.is() )
+ xSeek->seek(0);
+
+ Reference< XPropertySet > xStreamProp( xOutputStream, UNO_QUERY_THROW );
+ xStreamProp->setPropertyValue( INFO_MEDIATYPE, makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "text/xml" ) ) ) );
+ xStreamProp->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Compressed" ) ), makeAny( (sal_Bool)sal_True ) );
+
+ // write the stuff
+ WriteThroughComponent( xOutputStream, xComponent, pServiceName, _rArguments, rMediaDesc );
+}
+
+void ODatabaseDocument::WriteThroughComponent( const Reference< XOutputStream >& xOutputStream,
+ const Reference< XComponent >& xComponent, const sal_Char* pServiceName, const Sequence< Any >& _rArguments,
+ const Sequence< PropertyValue >& rMediaDesc ) const
+{
+ OSL_ENSURE( xOutputStream.is(), "I really need an output stream!" );
+ OSL_ENSURE( xComponent.is(), "Need component!" );
+ OSL_ENSURE( NULL != pServiceName, "Need component name!" );
+
+ // get component
+ Reference< XActiveDataSource > xSaxWriter;
+ OSL_VERIFY( m_pImpl->m_aContext.createComponent( "com.sun.star.xml.sax.Writer", xSaxWriter ) );
+ if ( !xSaxWriter.is() )
+ return;
+
+ // connect XML writer to output stream
+ xSaxWriter->setOutputStream( xOutputStream );
+
+ // prepare arguments (prepend doc handler to given arguments)
+ Reference< XDocumentHandler > xDocHandler( xSaxWriter,UNO_QUERY);
+ Sequence<Any> aArgs( 1 + _rArguments.getLength() );
+ aArgs[0] <<= xDocHandler;
+ for ( sal_Int32 i = 0; i < _rArguments.getLength(); ++i )
+ aArgs[ i+1 ] = _rArguments[i];
+
+ // get filter component
+ Reference< XExporter > xExporter;
+ OSL_VERIFY( m_pImpl->m_aContext.createComponentWithArguments( pServiceName, aArgs, xExporter ) );
+ if ( !xExporter.is() )
+ return;
+
+ // connect model and filter
+ xExporter->setSourceDocument( xComponent );
+
+ // filter
+ Reference< XFilter > xFilter( xExporter, UNO_QUERY_THROW );
+ xFilter->filter( rMediaDesc );
+}
+
+void ODatabaseDocument::impl_writeStorage_throw( const Reference< XStorage >& _rxTargetStorage, const ::comphelper::NamedValueCollection& _rMediaDescriptor ) const
+{
+ // extract status indicator
+ Sequence< Any > aDelegatorArguments;
+ lcl_extractStatusIndicator( _rMediaDescriptor, aDelegatorArguments );
+
+ /** property map for export info set */
+ comphelper::PropertyMapEntry aExportInfoMap[] =
+ {
+ { MAP_LEN( "BaseURI"), 0,&::getCppuType( (::rtl::OUString *)0 ),beans::PropertyAttribute::MAYBEVOID, 0 },
+ { MAP_LEN( "StreamName"), 0,&::getCppuType( (::rtl::OUString *)0 ),beans::PropertyAttribute::MAYBEVOID, 0 },
+ { MAP_LEN( "UsePrettyPrinting" ), 0, &::getCppuType((sal_Bool*)0), beans::PropertyAttribute::MAYBEVOID, 0},
+ { NULL, 0, 0, NULL, 0, 0 }
+ };
+ uno::Reference< beans::XPropertySet > xInfoSet( comphelper::GenericPropertySet_CreateInstance( new comphelper::PropertySetInfo( aExportInfoMap ) ) );
+
+ SvtSaveOptions aSaveOpt;
+ xInfoSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UsePrettyPrinting")), uno::makeAny(aSaveOpt.IsPrettyPrinting()));
+ if ( aSaveOpt.IsSaveRelFSys() )
+ xInfoSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BaseURI")), uno::makeAny(_rMediaDescriptor.getOrDefault("URL",::rtl::OUString())));
+
+ ::rtl::OUString aVersion;
+ SvtSaveOptions::ODFDefaultVersion nDefVersion = aSaveOpt.GetODFDefaultVersion();
+
+ // older versions can not have this property set, it exists only starting from ODF1.2
+ if ( nDefVersion >= SvtSaveOptions::ODFVER_012 )
+ aVersion = ODFVER_012_TEXT;
+
+ if ( aVersion.getLength() )
+ {
+ try
+ {
+ xInfoSet->setPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Version" )), uno::makeAny( aVersion ) );
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+
+ sal_Int32 nArgsLen = aDelegatorArguments.getLength();
+ aDelegatorArguments.realloc(nArgsLen+1);
+ aDelegatorArguments[nArgsLen++] <<= xInfoSet;
+
+ Reference< XPropertySet > xProp( _rxTargetStorage, UNO_QUERY_THROW );
+ xProp->setPropertyValue( INFO_MEDIATYPE, makeAny( (rtl::OUString)MIMETYPE_OASIS_OPENDOCUMENT_DATABASE ) );
+
+ Reference< XComponent > xComponent( *const_cast< ODatabaseDocument* >( this ), UNO_QUERY_THROW );
+
+ Sequence< PropertyValue > aMediaDescriptor;
+ _rMediaDescriptor >>= aMediaDescriptor;
+
+ xInfoSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StreamName")), uno::makeAny(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("settings.xml"))));
+ WriteThroughComponent( xComponent, "settings.xml", "com.sun.star.comp.sdb.XMLSettingsExporter",
+ aDelegatorArguments, aMediaDescriptor, _rxTargetStorage );
+
+ xInfoSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StreamName")), uno::makeAny(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("content.xml"))));
+ WriteThroughComponent( xComponent, "content.xml", "com.sun.star.comp.sdb.DBExportFilter",
+ aDelegatorArguments, aMediaDescriptor, _rxTargetStorage );
+
+ m_pImpl->storeLibraryContainersTo( _rxTargetStorage );
+}
+
+Reference< XUIConfigurationManager > SAL_CALL ODatabaseDocument::getUIConfigurationManager( ) throw (RuntimeException)
+{
+ DocumentGuard aGuard( *this );
+
+ if ( !m_xUIConfigurationManager.is() )
+ {
+ m_pImpl->m_aContext.createComponent( "com.sun.star.ui.UIConfigurationManager", m_xUIConfigurationManager );
+ Reference< XUIConfigurationStorage > xUIConfigStorage( m_xUIConfigurationManager, UNO_QUERY );
+ if ( xUIConfigStorage.is() )
+ {
+ rtl::OUString aUIConfigFolderName( RTL_CONSTASCII_USTRINGPARAM( "Configurations2" ));
+ Reference< XStorage > xConfigStorage;
+
+ // First try to open with READWRITE and then READ
+ xConfigStorage = getDocumentSubStorage( aUIConfigFolderName, ElementModes::READWRITE );
+ if ( xConfigStorage.is() )
+ {
+ rtl::OUString aUIConfigMediaType( RTL_CONSTASCII_USTRINGPARAM( "application/vnd.sun.xml.ui.configuration" ));
+ rtl::OUString aMediaType;
+ Reference< XPropertySet > xPropSet( xConfigStorage, UNO_QUERY );
+ Any a = xPropSet->getPropertyValue( INFO_MEDIATYPE );
+ if ( !( a >>= aMediaType ) || ( aMediaType.getLength() == 0 ))
+ {
+ a <<= aUIConfigMediaType;
+ xPropSet->setPropertyValue( INFO_MEDIATYPE, a );
+ }
+ }
+ else
+ xConfigStorage = getDocumentSubStorage( aUIConfigFolderName, ElementModes::READ );
+
+ // initialize ui configuration manager with document substorage
+ xUIConfigStorage->setStorage( xConfigStorage );
+ }
+ }
+
+ return m_xUIConfigurationManager;
+}
+
+Reference< XStorage > SAL_CALL ODatabaseDocument::getDocumentSubStorage( const ::rtl::OUString& aStorageName, sal_Int32 nMode ) throw (RuntimeException)
+{
+ DocumentGuard aGuard( *this );
+
+ Reference< XDocumentSubStorageSupplier > xStorageAccess( m_pImpl->getDocumentSubStorageSupplier() );
+ return xStorageAccess->getDocumentSubStorage( aStorageName, nMode );
+}
+
+Sequence< ::rtl::OUString > SAL_CALL ODatabaseDocument::getDocumentSubStoragesNames( ) throw (::com::sun::star::io::IOException, RuntimeException)
+{
+ Reference< XDocumentSubStorageSupplier > xStorageAccess( m_pImpl->getDocumentSubStorageSupplier() );
+ return xStorageAccess->getDocumentSubStoragesNames();
+}
+
+void ODatabaseDocument::impl_notifyStorageChange_nolck_nothrow( const Reference< XStorage >& _rxNewRootStorage )
+{
+ Reference< XInterface > xMe( *const_cast< ODatabaseDocument* >( this ) );
+
+ m_aStorageListeners.forEach< XStorageChangeListener >(
+ boost::bind( &XStorageChangeListener::notifyStorageChange, _1, boost::cref( xMe ), boost::cref( _rxNewRootStorage ) ) );
+}
+
+void ODatabaseDocument::disposing()
+{
+ OSL_TRACE( "DD: disp: %p: %p", this, m_pImpl.get() );
+ if ( !m_pImpl.is() )
+ {
+ // this means that we're already disposed
+ DBG_ASSERT( ODatabaseDocument_OfficeDocument::rBHelper.bDisposed, "ODatabaseDocument::disposing: no impl anymore, but not yet disposed!" );
+ return;
+ }
+
+ if ( impl_isInitialized() )
+ m_aEventNotifier.notifyDocumentEvent( "OnUnload" );
+
+ Reference< XModel > xHoldAlive( this );
+
+ m_aEventNotifier.disposing();
+
+ lang::EventObject aDisposeEvent(static_cast<XWeak*>(this));
+ m_aModifyListeners.disposeAndClear( aDisposeEvent );
+ m_aCloseListener.disposeAndClear( aDisposeEvent );
+ m_aStorageListeners.disposeAndClear( aDisposeEvent );
+
+ // this is the list of objects which we currently hold as member. Upon resetting
+ // those members, we can (potentially) release the last reference to them, in which
+ // case they will be deleted - if they're C++ implementations, that is :).
+ // Some of those implementations are offending enough to require the SolarMutex, which
+ // means we should not release the last reference while our own mutex is locked ...
+ ::std::list< Reference< XInterface > > aKeepAlive;
+
+ // SYNCHRONIZED ->
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+
+ DBG_ASSERT( m_aControllers.empty(), "ODatabaseDocument::disposing: there still are controllers!" );
+ // normally, nobody should explicitly dispose, but only XCloseable::close the document. And upon
+ // closing, our controllers are closed, too
+
+ aKeepAlive.push_back( m_xUIConfigurationManager );
+ m_xUIConfigurationManager = NULL;
+
+ clearObjectContainer( m_xForms );
+ clearObjectContainer( m_xReports );
+
+ // reset the macro mode: in case the our impl struct stays alive (e.g. because our DataSource
+ // object still exists), and somebody subsequently re-opens the document, we want to have
+ // the security warning, again.
+ m_pImpl->resetMacroExecutionMode();
+
+ // similar argueing for our ViewMonitor
+ m_aViewMonitor.reset();
+
+ // tell our Impl to forget us
+ m_pImpl->modelIsDisposing( impl_isInitialized(), ODatabaseModelImpl::ResetModelAccess() );
+
+ // now, at the latest, the controller array should be empty. Controllers are
+ // expected to listen for our disposal, and disconnect then
+ DBG_ASSERT( m_aControllers.empty(), "ODatabaseDocument::disposing: there still are controllers!" );
+ impl_disposeControllerFrames_nothrow();
+
+ aKeepAlive.push_back( m_xModuleManager );
+ m_xModuleManager.clear();
+
+ aKeepAlive.push_back( m_xTitleHelper );
+ m_xTitleHelper.clear();
+
+ m_pImpl.clear();
+
+ aGuard.clear();
+ // <- SYNCHRONIZED
+
+ aKeepAlive.clear();
+}
+
+// XComponent
+void SAL_CALL ODatabaseDocument::dispose( ) throw (RuntimeException)
+{
+ ::cppu::WeakComponentImplHelperBase::dispose();
+}
+
+void SAL_CALL ODatabaseDocument::addEventListener( const Reference< lang::XEventListener >& _xListener ) throw (RuntimeException)
+{
+ ::cppu::WeakComponentImplHelperBase::addEventListener( _xListener );
+}
+
+void SAL_CALL ODatabaseDocument::removeEventListener( const Reference< lang::XEventListener >& _xListener ) throw (RuntimeException)
+{
+ ::cppu::WeakComponentImplHelperBase::removeEventListener( _xListener );
+}
+
+// XServiceInfo
+rtl::OUString ODatabaseDocument::getImplementationName( ) throw(RuntimeException)
+{
+ return getImplementationName_static();
+}
+
+rtl::OUString ODatabaseDocument::getImplementationName_static( ) throw(RuntimeException)
+{
+ return rtl::OUString::createFromAscii("com.sun.star.comp.dba.ODatabaseDocument");
+}
+
+Sequence< ::rtl::OUString > ODatabaseDocument::getSupportedServiceNames( ) throw (RuntimeException)
+{
+ return getSupportedServiceNames_static();
+}
+
+Reference< XInterface > ODatabaseDocument::Create( const Reference< XComponentContext >& _rxContext )
+{
+ ::comphelper::ComponentContext aContext( _rxContext );
+ Reference< XUnoTunnel > xDBContextTunnel( aContext.createComponent( (::rtl::OUString)SERVICE_SDB_DATABASECONTEXT ), UNO_QUERY_THROW );
+ ODatabaseContext* pContext = reinterpret_cast< ODatabaseContext* >( xDBContextTunnel->getSomething( ODatabaseContext::getUnoTunnelImplementationId() ) );
+
+ ::rtl::Reference<ODatabaseModelImpl> pImpl( new ODatabaseModelImpl( aContext.getLegacyServiceFactory(), *pContext ) );
+ Reference< XModel > xModel( pImpl->createNewModel_deliverOwnership( false ) );
+ return xModel.get();
+}
+
+Sequence< ::rtl::OUString > ODatabaseDocument::getSupportedServiceNames_static( ) throw (RuntimeException)
+{
+ Sequence< ::rtl::OUString > aSNS( 2 );
+ aSNS[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdb.OfficeDatabaseDocument"));
+ aSNS[1] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.document.OfficeDocument"));
+ return aSNS;
+}
+
+sal_Bool ODatabaseDocument::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException)
+{
+ return ::comphelper::findValue(getSupportedServiceNames(), _rServiceName, sal_True).getLength() != 0;
+}
+
+Reference< XDataSource > SAL_CALL ODatabaseDocument::getDataSource() throw (RuntimeException)
+{
+ DocumentGuard aGuard( *this, DocumentGuard::MethodWithoutInit );
+ return m_pImpl->getOrCreateDataSource();
+}
+
+void SAL_CALL ODatabaseDocument::loadFromStorage( const Reference< XStorage >& /*xStorage*/, const Sequence< PropertyValue >& /*aMediaDescriptor*/ ) throw (IllegalArgumentException, DoubleInitializationException, IOException, Exception, RuntimeException)
+{
+ DocumentGuard aGuard( *this );
+
+ throw Exception(
+ DBACORE_RESSTRING( RID_STR_NO_EMBEDDING ),
+ *this
+ );
+}
+
+void SAL_CALL ODatabaseDocument::storeToStorage( const Reference< XStorage >& _rxStorage, const Sequence< PropertyValue >& _rMediaDescriptor ) throw (IllegalArgumentException, IOException, Exception, RuntimeException)
+{
+ DocumentGuard aGuard( *this );
+ impl_storeToStorage_throw( _rxStorage, _rMediaDescriptor, aGuard );
+}
+
+void SAL_CALL ODatabaseDocument::switchToStorage( const Reference< XStorage >& _rxNewRootStorage ) throw (IllegalArgumentException, IOException, Exception, RuntimeException)
+{
+ DocumentGuard aGuard( *this );
+
+ Reference< XStorage > xNewRootStorage( m_pImpl->switchToStorage( _rxNewRootStorage ) );
+
+ aGuard.clear();
+ impl_notifyStorageChange_nolck_nothrow( xNewRootStorage );
+}
+
+Reference< XStorage > SAL_CALL ODatabaseDocument::getDocumentStorage( ) throw (IOException, Exception, RuntimeException)
+{
+ DocumentGuard aGuard( *this );
+ return m_pImpl->getOrCreateRootStorage();
+}
+
+void SAL_CALL ODatabaseDocument::addStorageChangeListener( const Reference< XStorageChangeListener >& _Listener ) throw (RuntimeException)
+{
+ DocumentGuard aGuard( *this );
+ m_aStorageListeners.addInterface( _Listener );
+}
+
+void SAL_CALL ODatabaseDocument::removeStorageChangeListener( const Reference< XStorageChangeListener >& _Listener ) throw (RuntimeException)
+{
+ DocumentGuard aGuard( *this );
+ m_aStorageListeners.addInterface( _Listener );
+}
+
+Reference< XStorageBasedLibraryContainer > SAL_CALL ODatabaseDocument::getBasicLibraries() throw (RuntimeException)
+{
+ DocumentGuard aGuard( *this, DocumentGuard::MethodUsedDuringInit );
+ return m_pImpl->getLibraryContainer( true );
+}
+
+Reference< XStorageBasedLibraryContainer > SAL_CALL ODatabaseDocument::getDialogLibraries() throw (RuntimeException)
+{
+ DocumentGuard aGuard( *this );
+ return m_pImpl->getLibraryContainer( false );
+}
+
+::sal_Bool SAL_CALL ODatabaseDocument::getAllowMacroExecution() throw (RuntimeException)
+{
+ DocumentGuard aGuard( *this );
+ return m_pImpl->adjustMacroMode_AutoReject();
+}
+
+Reference< XEmbeddedScripts > SAL_CALL ODatabaseDocument::getScriptContainer() throw (RuntimeException)
+{
+ DocumentGuard aGuard( *this );
+ return this;
+}
+
+Reference< provider::XScriptProvider > SAL_CALL ODatabaseDocument::getScriptProvider( ) throw (RuntimeException)
+{
+ DocumentGuard aGuard( *this );
+
+ Reference< XScriptProvider > xScriptProvider( m_xScriptProvider );
+ if ( !xScriptProvider.is() )
+ {
+ Reference < XScriptProviderFactory > xFactory(
+ m_pImpl->m_aContext.getSingleton( "com.sun.star.script.provider.theMasterScriptProviderFactory" ), UNO_QUERY_THROW );
+
+ Any aScriptProviderContext;
+ if ( m_bAllowDocumentScripting )
+ aScriptProviderContext <<= Reference< XModel >( this );
+
+ xScriptProvider.set( xFactory->createScriptProvider( aScriptProviderContext ), UNO_SET_THROW );
+ m_xScriptProvider = xScriptProvider;
+ }
+
+ return xScriptProvider;
+}
+
+Reference< XNameReplace > SAL_CALL ODatabaseDocument::getEvents( ) throw (RuntimeException)
+{
+ DocumentGuard aGuard( *this, DocumentGuard::MethodUsedDuringInit );
+ return m_pEventContainer;
+}
+
+void SAL_CALL ODatabaseDocument::disposing( const ::com::sun::star::lang::EventObject& Source ) throw(RuntimeException)
+{
+ if ( m_pImpl.is() )
+ m_pImpl->disposing(Source);
+}
+
+Reference< XInterface > ODatabaseDocument::getThis() const
+{
+ return *const_cast< ODatabaseDocument* >( this );
+}
+
+struct CreateAny : public ::std::unary_function< Reference<XController>, Any>
+{
+ Any operator() (const Reference<XController>& lhs) const
+ {
+ return makeAny(lhs);
+ }
+};
+
+// XModel2
+Reference< XEnumeration > SAL_CALL ODatabaseDocument::getControllers( ) throw (RuntimeException)
+{
+ DocumentGuard aGuard( *this );
+ uno::Sequence< Any> aController( m_aControllers.size() );
+ ::std::transform( m_aControllers.begin(), m_aControllers.end(), aController.getArray(), CreateAny() );
+ return new ::comphelper::OAnyEnumeration(aController);
+}
+
+Sequence< ::rtl::OUString > SAL_CALL ODatabaseDocument::getAvailableViewControllerNames( ) throw (RuntimeException)
+{
+ Sequence< ::rtl::OUString > aNames(1);
+ aNames[0] = SERVICE_SDB_APPLICATIONCONTROLLER;
+ return aNames;
+}
+
+Reference< XController2 > SAL_CALL ODatabaseDocument::createDefaultViewController( const Reference< XFrame >& _Frame ) throw (IllegalArgumentException, Exception, RuntimeException)
+{
+ return createViewController(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Default" ) ),
+ Sequence< PropertyValue >(),
+ _Frame
+ );
+}
+
+Reference< XController2 > SAL_CALL ODatabaseDocument::createViewController( const ::rtl::OUString& _ViewName, const Sequence< PropertyValue >& _Arguments, const Reference< XFrame >& _Frame ) throw (IllegalArgumentException, Exception, RuntimeException)
+{
+ if ( !_ViewName.equalsAscii( "Default" ) && !_ViewName.equalsAscii( "Preview" ) )
+ throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
+ if ( !_Frame.is() )
+ throw IllegalArgumentException( ::rtl::OUString(), *this, 3 );
+
+ DocumentGuard aGuard( *this );
+ ::comphelper::ComponentContext aContext( m_pImpl->m_aContext );
+ aGuard.clear();
+
+ Reference< XController2 > xController;
+ aContext.createComponent( "org.openoffice.comp.dbu.OApplicationController", xController );
+
+ ::comphelper::NamedValueCollection aInitArgs( _Arguments );
+ aInitArgs.put( "Frame", _Frame );
+ if ( _ViewName.equalsAscii( "Preview" ) )
+ aInitArgs.put( "Preview", sal_Bool( sal_True ) );
+ Reference< XInitialization > xInitController( xController, UNO_QUERY_THROW );
+ xInitController->initialize( aInitArgs.getWrappedPropertyValues() );
+
+ return xController;
+}
+
+Reference< XTitle > ODatabaseDocument::impl_getTitleHelper_throw()
+{
+ if ( ! m_xTitleHelper.is ())
+ {
+ Reference< XUntitledNumbers > xDesktop(
+ m_pImpl->m_aContext.createComponent( "com.sun.star.frame.Desktop" ),
+ UNO_QUERY_THROW );
+ uno::Reference< frame::XModel > xThis (getThis(), uno::UNO_QUERY_THROW);
+
+ ::framework::TitleHelper* pHelper = new ::framework::TitleHelper(m_pImpl->m_aContext.getLegacyServiceFactory());
+ m_xTitleHelper.set(static_cast< ::cppu::OWeakObject* >(pHelper), uno::UNO_QUERY_THROW);
+ pHelper->setOwner (xThis );
+ pHelper->connectWithUntitledNumbers (xDesktop);
+ }
+
+ return m_xTitleHelper;
+}
+
+uno::Reference< frame::XUntitledNumbers > ODatabaseDocument::impl_getUntitledHelper_throw(const uno::Reference< uno::XInterface >& _xComponent)
+{
+ if ( !m_xModuleManager.is() )
+ m_xModuleManager.set( m_pImpl->m_aContext.createComponent( "com.sun.star.frame.ModuleManager" ), UNO_QUERY_THROW );
+
+ ::rtl::OUString sModuleId;
+ try
+ {
+ sModuleId = m_xModuleManager->identify( _xComponent );
+ }
+ catch(uno::Exception)
+ {
+ // ni
+ }
+ uno::Reference< frame::XUntitledNumbers > xNumberedControllers;
+
+ TNumberedController::iterator aFind = m_aNumberedControllers.find(sModuleId);
+ if ( aFind == m_aNumberedControllers.end() )
+ {
+ uno::Reference< frame::XModel > xThis(static_cast< frame::XModel* >(this), uno::UNO_QUERY_THROW);
+ ::comphelper::NumberedCollection* pHelper = new ::comphelper::NumberedCollection();
+ xNumberedControllers.set(static_cast< ::cppu::OWeakObject* >(pHelper), uno::UNO_QUERY_THROW);
+
+ pHelper->setOwner (xThis);
+ //pHelper->setUntitledPrefix (::rtl::OUString::createFromAscii(" : "));
+
+ m_aNumberedControllers.insert(TNumberedController::value_type(sModuleId,xNumberedControllers));
+ }
+ else
+ xNumberedControllers = aFind->second;
+
+ return xNumberedControllers;
+}
+
+// css.frame.XTitle
+::rtl::OUString SAL_CALL ODatabaseDocument::getTitle()
+ throw (uno::RuntimeException)
+{
+ // SYNCHRONIZED ->
+ DocumentGuard aGuard( *this, DocumentGuard::MethodUsedDuringInit );
+ return impl_getTitleHelper_throw()->getTitle();
+}
+
+// css.frame.XTitle
+void SAL_CALL ODatabaseDocument::setTitle( const ::rtl::OUString& sTitle )
+ throw (uno::RuntimeException)
+{
+ // SYNCHRONIZED ->
+ DocumentGuard aGuard( *this );
+ impl_getTitleHelper_throw()->setTitle( sTitle );
+ m_aEventNotifier.notifyDocumentEventAsync( "OnTitleChanged" );
+ // <- SYNCHRONIZED
+}
+
+// css.frame.XTitleChangeBroadcaster
+void SAL_CALL ODatabaseDocument::addTitleChangeListener( const uno::Reference< frame::XTitleChangeListener >& xListener )
+ throw (uno::RuntimeException)
+{
+ // SYNCHRONIZED ->
+ DocumentGuard aGuard( *this );
+
+ uno::Reference< frame::XTitleChangeBroadcaster > xBroadcaster( impl_getTitleHelper_throw(), uno::UNO_QUERY_THROW );
+ xBroadcaster->addTitleChangeListener( xListener );
+}
+
+// css.frame.XTitleChangeBroadcaster
+void SAL_CALL ODatabaseDocument::removeTitleChangeListener( const uno::Reference< frame::XTitleChangeListener >& xListener )
+ throw (uno::RuntimeException)
+{
+ // SYNCHRONIZED ->
+ DocumentGuard aGuard( *this );
+
+ uno::Reference< frame::XTitleChangeBroadcaster > xBroadcaster( impl_getTitleHelper_throw(), uno::UNO_QUERY_THROW );
+ xBroadcaster->removeTitleChangeListener( xListener );
+}
+
+// css.frame.XUntitledNumbers
+::sal_Int32 SAL_CALL ODatabaseDocument::leaseNumber( const uno::Reference< uno::XInterface >& xComponent )
+ throw (lang::IllegalArgumentException,
+ uno::RuntimeException )
+{
+ DocumentGuard aGuard( *this );
+ return impl_getUntitledHelper_throw(xComponent)->leaseNumber (xComponent);
+}
+
+// css.frame.XUntitledNumbers
+void SAL_CALL ODatabaseDocument::releaseNumber( ::sal_Int32 nNumber )
+ throw (lang::IllegalArgumentException,
+ uno::RuntimeException )
+{
+ DocumentGuard aGuard( *this );
+ impl_getUntitledHelper_throw()->releaseNumber (nNumber);
+}
+
+// css.frame.XUntitledNumbers
+void SAL_CALL ODatabaseDocument::releaseNumberForComponent( const uno::Reference< uno::XInterface >& xComponent )
+ throw (lang::IllegalArgumentException,
+ uno::RuntimeException )
+{
+ DocumentGuard aGuard( *this );
+ impl_getUntitledHelper_throw(xComponent)->releaseNumberForComponent (xComponent);
+}
+
+// css.frame.XUntitledNumbers
+::rtl::OUString SAL_CALL ODatabaseDocument::getUntitledPrefix() throw (uno::RuntimeException)
+{
+ return ::rtl::OUString();/*RTL_CONSTASCII_USTRINGPARAM(" : "));*/
+}
+
+} // namespace dbaccess
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/databasedocument.hxx b/dbaccess/source/core/dataaccess/databasedocument.hxx
new file mode 100644
index 000000000000..9659c033260c
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/databasedocument.hxx
@@ -0,0 +1,709 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _DBA_COREDATAACCESS_DATABASEDOCUMENT_HXX_
+#define _DBA_COREDATAACCESS_DATABASEDOCUMENT_HXX_
+
+#include "ModelImpl.hxx"
+#include "documenteventnotifier.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/document/XDocumentSubStorageSupplier.hpp>
+#include <com/sun/star/frame/XModel2.hpp>
+#include <com/sun/star/frame/XTitle.hpp>
+#include <com/sun/star/frame/XTitleChangeBroadcaster.hpp>
+#include <com/sun/star/frame/XUntitledNumbers.hpp>
+#include <com/sun/star/util/XModifiable.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/sdb/XReportDocumentsSupplier.hpp>
+#include <com/sun/star/sdb/XFormDocumentsSupplier.hpp>
+#include <com/sun/star/util/XCloseable.hpp>
+#include <com/sun/star/view/XPrintable.hpp>
+#include <com/sun/star/frame/XModuleManager.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/sdb/XOfficeDatabaseDocument.hpp>
+#include <com/sun/star/embed/XTransactionListener.hpp>
+#include <com/sun/star/document/XStorageBasedDocument.hpp>
+#include <com/sun/star/document/XEmbeddedScripts.hpp>
+#include <com/sun/star/document/XEventsSupplier.hpp>
+#include <com/sun/star/document/XScriptInvocationContext.hpp>
+#include <com/sun/star/script/XStorageBasedLibraryContainer.hpp>
+#include <com/sun/star/script/provider/XScriptProviderSupplier.hpp>
+#include <com/sun/star/frame/XLoadable.hpp>
+#include <com/sun/star/document/XEventBroadcaster.hpp>
+#include <com/sun/star/document/XDocumentEventBroadcaster.hpp>
+#include <com/sun/star/document/XDocumentRecovery.hpp>
+/** === end UNO includes === **/
+
+#if ! defined(INCLUDED_COMPHELPER_IMPLBASE_VAR_HXX_17)
+#define INCLUDED_COMPHELPER_IMPLBASE_VAR_HXX_17
+#define COMPHELPER_IMPLBASE_INTERFACE_NUMBER 17
+#include <comphelper/implbase_var.hxx>
+#endif
+
+#include <cppuhelper/compbase10.hxx>
+#include <cppuhelper/implbase3.hxx>
+#include <rtl/ref.hxx>
+
+#include <boost/shared_ptr.hpp>
+#include <boost/noncopyable.hpp>
+
+namespace comphelper {
+ class NamedValueCollection;
+}
+
+//........................................................................
+namespace dbaccess
+{
+//........................................................................
+
+class DocumentEvents;
+class DocumentEventExecutor;
+class DocumentGuard;
+
+typedef ::std::vector< ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController > > Controllers;
+
+//============================================================
+//= ViewMonitor
+//============================================================
+/** helper class monitoring the views of a document, and firing appropriate events
+ when views are attached / detached
+*/
+class ViewMonitor : public boost::noncopyable
+{
+public:
+ ViewMonitor( DocumentEventNotifier& _rEventNotifier )
+ :m_rEventNotifier( _rEventNotifier )
+ ,m_bIsNewDocument( true )
+ ,m_bEverHadController( false )
+ ,m_bLastIsFirstEverController( false )
+ ,m_xLastConnectedController()
+ {
+ }
+
+ void reset()
+ {
+ m_bEverHadController = false;
+ m_bLastIsFirstEverController = false;
+ m_xLastConnectedController.clear();
+ }
+
+ /** to be called when a view (aka controller) has been connected to the document
+ @return
+ <TRUE/> if and only if this was the first-ever controller connected to the document
+ */
+ bool onControllerConnected(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController >& _rxController
+ );
+
+ /** to be called when a controller is set as current controller
+ @return <TRUE/>
+ if and only if the controller connection indicates that loading the document is finished. This
+ is the case if the given controller has previously been connected, and it was the first controller
+ ever for which this happened.
+ */
+ bool onSetCurrentController(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController >& _rxController
+ );
+
+ void onLoadedDocument() { m_bIsNewDocument = false; }
+
+private:
+ DocumentEventNotifier& m_rEventNotifier;
+ bool m_bIsNewDocument;
+ bool m_bEverHadController;
+ bool m_bLastIsFirstEverController;
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController >
+ m_xLastConnectedController;
+};
+
+//============================================================
+//= ODatabaseDocument
+//============================================================
+typedef ::comphelper::WeakComponentImplHelper17 < ::com::sun::star::frame::XModel2
+ , ::com::sun::star::util::XModifiable
+ , ::com::sun::star::frame::XStorable
+ , ::com::sun::star::document::XEventBroadcaster
+ , ::com::sun::star::document::XDocumentEventBroadcaster
+ , ::com::sun::star::view::XPrintable
+ , ::com::sun::star::util::XCloseable
+ , ::com::sun::star::lang::XServiceInfo
+ , ::com::sun::star::sdb::XOfficeDatabaseDocument
+ , ::com::sun::star::ui::XUIConfigurationManagerSupplier
+ , ::com::sun::star::document::XStorageBasedDocument
+ , ::com::sun::star::document::XEmbeddedScripts
+ , ::com::sun::star::document::XScriptInvocationContext
+ , ::com::sun::star::script::provider::XScriptProviderSupplier
+ , ::com::sun::star::document::XEventsSupplier
+ , ::com::sun::star::frame::XLoadable
+ , ::com::sun::star::document::XDocumentRecovery
+ > ODatabaseDocument_OfficeDocument;
+
+typedef ::cppu::ImplHelper3< ::com::sun::star::frame::XTitle
+ , ::com::sun::star::frame::XTitleChangeBroadcaster
+ , ::com::sun::star::frame::XUntitledNumbers
+ > ODatabaseDocument_Title;
+
+class ODatabaseDocument :public ModelDependentComponent // ModelDependentComponent must be first!
+ ,public ODatabaseDocument_OfficeDocument
+ ,public ODatabaseDocument_Title
+{
+ enum InitState
+ {
+ NotInitialized,
+ Initializing,
+ Initialized
+ };
+
+ DECLARE_STL_USTRINGACCESS_MAP(::com::sun::star::uno::Reference< ::com::sun::star::frame::XUntitledNumbers >,TNumberedController);
+ ::com::sun::star::uno::Reference< ::com::sun::star::ui::XUIConfigurationManager> m_xUIConfigurationManager;
+
+ ::cppu::OInterfaceContainerHelper m_aModifyListeners;
+ ::cppu::OInterfaceContainerHelper m_aCloseListener;
+ ::cppu::OInterfaceContainerHelper m_aStorageListeners;
+
+ DocumentEvents* m_pEventContainer;
+ ::rtl::Reference< DocumentEventExecutor > m_pEventExecutor;
+ DocumentEventNotifier m_aEventNotifier;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController > m_xCurrentController;
+ Controllers m_aControllers;
+ ViewMonitor m_aViewMonitor;
+
+ ::com::sun::star::uno::WeakReference< ::com::sun::star::container::XNameAccess > m_xForms;
+ ::com::sun::star::uno::WeakReference< ::com::sun::star::container::XNameAccess > m_xReports;
+ ::com::sun::star::uno::WeakReference< ::com::sun::star::script::provider::XScriptProvider > m_xScriptProvider;
+
+ /** @short such module manager is used to classify new opened documents. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModuleManager > m_xModuleManager;
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XTitle > m_xTitleHelper;
+ TNumberedController m_aNumberedControllers;
+
+ /** true if and only if the DatabaseDocument's "initNew" or "load" have been called (or, well,
+ the document has be initialized implicitly - see storeAsURL
+ */
+ InitState m_eInitState;
+ bool m_bClosing;
+ bool m_bAllowDocumentScripting;
+ bool m_bHasBeenRecovered;
+
+ enum StoreType { SAVE, SAVE_AS };
+ /** stores the document to the given URL, rebases it to the respective new storage, if necessary, resets
+ the modified flag, and notifies any listeners as required
+
+ @param _rURL
+ the URL to store the document to
+ @param _rArguments
+ arguments for storing the document (MediaDescriptor)
+ @param _eType
+ the type of the store process (Save or SaveAs). The method will automatically
+ notify the proper events for this type.
+ @param _rGuard
+ the instance lock to be released before doing synchronous notifications
+ */
+ void impl_storeAs_throw(
+ const ::rtl::OUString& _rURL,
+ const ::comphelper::NamedValueCollection& _rArguments,
+ const StoreType _eType,
+ DocumentGuard& _rGuard
+ )
+ throw ( ::com::sun::star::io::IOException
+ , ::com::sun::star::uno::RuntimeException );
+
+ /** notifies our storage change listeners that our underlying storage changed
+
+ @param _rxNewRootStorage
+ the new root storage to be notified. If <NULL/>, it is assumed that no storage change actually
+ happened, and the listeners are not notified.
+ */
+ void impl_notifyStorageChange_nolck_nothrow(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& _rxNewRootStorage
+ );
+
+ /// write a single XML stream into the package
+ void WriteThroughComponent(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > & xComponent, /// the component we export
+ const sal_Char* pStreamName, /// the stream name
+ const sal_Char* pServiceName, /// service name of the component
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any> & rArguments, /// the argument (XInitialization)
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue> & rMediaDesc,/// output descriptor
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& _xStorageToSaveTo
+ ) const;
+
+
+ /// write a single output stream
+ /// (to be called either directly or by WriteThroughComponent(...))
+ void WriteThroughComponent(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xOutputStream,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& xComponent,
+ const sal_Char* pServiceName,
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& rArguments,
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue> & rMediaDesc
+ ) const;
+
+ /** writes the content and settings
+ @param sURL
+ The URL
+ @param lArguments
+ The media descriptor
+ @param _xStorageToSaveTo
+ The storage which should be used for saving
+ */
+ void impl_writeStorage_throw(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& _rxTargetStorage,
+ const ::comphelper::NamedValueCollection& _rMediaDescriptor
+ ) const;
+
+ // ModelDependentComponent overridables
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > getThis() const;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XTitle > impl_getTitleHelper_throw();
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XUntitledNumbers > impl_getUntitledHelper_throw(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _xComponent = ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >());
+
+private:
+ ODatabaseDocument(const ::rtl::Reference<ODatabaseModelImpl>& _pImpl);
+ // Do NOT create those documents directly, always use ODatabaseModelImpl::getModel. Reason is that
+ // ODatabaseDocument requires clear ownership, and in turn lifetime synchronisation with the ModelImpl.
+ // If you create a ODatabaseDocument directly, you might easily create a leak.
+ // #i50905# / 2005-06-20 / frank.schonheit@sun.com
+
+protected:
+ virtual void SAL_CALL disposing();
+
+ virtual ~ODatabaseDocument();
+
+public:
+ struct FactoryAccess { friend class ODatabaseModelImpl; private: FactoryAccess() { } };
+ static ODatabaseDocument* createDatabaseDocument( const ::rtl::Reference<ODatabaseModelImpl>& _pImpl, FactoryAccess /*accessControl*/ )
+ {
+ return new ODatabaseDocument( _pImpl );
+ }
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::lang::XServiceInfo - static methods
+ static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_static(void) throw( ::com::sun::star::uno::RuntimeException );
+ static ::rtl::OUString getImplementationName_static(void) throw( ::com::sun::star::uno::RuntimeException );
+ static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >
+ SAL_CALL Create(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >&);
+
+ // XInterface
+ virtual ::com::sun::star::uno::Any SAL_CALL queryInterface(const ::com::sun::star::uno::Type& _rType) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL acquire( ) throw ();
+ virtual void SAL_CALL release( ) throw ();
+
+ // XTypeProvider
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException);
+
+ // XComponent
+ virtual void SAL_CALL dispose( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XModel
+ virtual sal_Bool SAL_CALL attachResource( const ::rtl::OUString& URL, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& Arguments ) throw (::com::sun::star::uno::RuntimeException) ;
+ virtual ::rtl::OUString SAL_CALL getURL( ) throw (::com::sun::star::uno::RuntimeException) ;
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL getArgs( ) throw (::com::sun::star::uno::RuntimeException) ;
+ virtual void SAL_CALL connectController( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController >& Controller ) throw (::com::sun::star::uno::RuntimeException) ;
+ virtual void SAL_CALL disconnectController( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController >& Controller ) throw (::com::sun::star::uno::RuntimeException) ;
+ virtual void SAL_CALL lockControllers( ) throw (::com::sun::star::uno::RuntimeException) ;
+ virtual void SAL_CALL unlockControllers( ) throw (::com::sun::star::uno::RuntimeException) ;
+ virtual sal_Bool SAL_CALL hasControllersLocked( ) throw (::com::sun::star::uno::RuntimeException) ;
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController > SAL_CALL getCurrentController( ) throw (::com::sun::star::uno::RuntimeException) ;
+ virtual void SAL_CALL setCurrentController( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController >& Controller ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException) ;
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL getCurrentSelection( ) throw (::com::sun::star::uno::RuntimeException) ;
+
+ // XModel2
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumeration > SAL_CALL getControllers( ) throw (::com::sun::star::uno::RuntimeException) ;
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getAvailableViewControllerNames( ) throw (::com::sun::star::uno::RuntimeException) ;
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController2 > SAL_CALL createDefaultViewController( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& Frame ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) ;
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController2 > SAL_CALL createViewController( const ::rtl::OUString& ViewName, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& Arguments, const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& Frame ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) ;
+
+ // XStorable
+ virtual sal_Bool SAL_CALL hasLocation( ) throw (::com::sun::star::uno::RuntimeException) ;
+ virtual ::rtl::OUString SAL_CALL getLocation( ) throw (::com::sun::star::uno::RuntimeException) ;
+ virtual sal_Bool SAL_CALL isReadonly( ) throw (::com::sun::star::uno::RuntimeException) ;
+ virtual void SAL_CALL store( ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) ;
+ virtual void SAL_CALL storeAsURL( const ::rtl::OUString& sURL, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& lArguments ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) ;
+ virtual void SAL_CALL storeToURL( const ::rtl::OUString& sURL, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& lArguments ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) ;
+
+ // XModifyBroadcaster
+ virtual void SAL_CALL addModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::util::XModifiable
+ virtual sal_Bool SAL_CALL isModified( ) throw (::com::sun::star::uno::RuntimeException) ;
+ virtual void SAL_CALL setModified( sal_Bool bModified ) throw (::com::sun::star::beans::PropertyVetoException, ::com::sun::star::uno::RuntimeException) ;
+
+ // XEventBroadcaster
+ virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::document::XEventListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::document::XEventListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XDocumentEventBroadcaster
+ virtual void SAL_CALL addDocumentEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::document::XDocumentEventListener >& _Listener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeDocumentEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::document::XDocumentEventListener >& _Listener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL notifyDocumentEvent( const ::rtl::OUString& _EventName, const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController2 >& _ViewController, const ::com::sun::star::uno::Any& _Supplement ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException);
+
+ // XPrintable
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL getPrinter( ) throw (::com::sun::star::uno::RuntimeException) ;
+ virtual void SAL_CALL setPrinter( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aPrinter ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) ;
+ virtual void SAL_CALL print( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& xOptions ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) ;
+
+ // XFormDocumentsSupplier
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL getFormDocuments( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XReportDocumentsSupplier
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL getReportDocuments( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XCloseable
+ virtual void SAL_CALL close( sal_Bool DeliverOwnership ) throw (::com::sun::star::util::CloseVetoException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addCloseListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloseListener >& Listener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeCloseListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloseListener >& Listener ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XUIConfigurationManagerSupplier
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::ui::XUIConfigurationManager > SAL_CALL getUIConfigurationManager( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XDocumentSubStorageSupplier
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > SAL_CALL getDocumentSubStorage( const ::rtl::OUString& aStorageName, sal_Int32 nMode ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getDocumentSubStoragesNames( ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ // XOfficeDatabaseDocument
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDataSource > SAL_CALL getDataSource() throw (::com::sun::star::uno::RuntimeException);
+
+ // XStorageBasedDocument
+ virtual void SAL_CALL loadFromStorage( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aMediaDescriptor ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::frame::DoubleInitializationException, ::com::sun::star::io::IOException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL storeToStorage( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aMediaDescriptor ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::io::IOException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL switchToStorage( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::io::IOException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > SAL_CALL getDocumentStorage( ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addStorageChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::document::XStorageChangeListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeStorageChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::document::XStorageChangeListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XEmbeddedScripts
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::script::XStorageBasedLibraryContainer > SAL_CALL getBasicLibraries() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::script::XStorageBasedLibraryContainer > SAL_CALL getDialogLibraries() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL getAllowMacroExecution() throw (::com::sun::star::uno::RuntimeException);
+
+ // XScriptInvocationContext
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::document::XEmbeddedScripts > SAL_CALL getScriptContainer() throw (::com::sun::star::uno::RuntimeException);
+
+ // XScriptProviderSupplier
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::script::provider::XScriptProvider > SAL_CALL getScriptProvider( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XEventsSupplier
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameReplace > SAL_CALL getEvents( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XLoadable
+ virtual void SAL_CALL initNew( ) throw (::com::sun::star::frame::DoubleInitializationException, ::com::sun::star::io::IOException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL load( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& lArguments ) throw (::com::sun::star::frame::DoubleInitializationException, ::com::sun::star::io::IOException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+
+ // css.document.XDocumentRecovery
+ virtual ::sal_Bool SAL_CALL wasModifiedSinceLastSave() throw ( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL storeToRecoveryFile( const ::rtl::OUString& i_TargetLocation, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& i_MediaDescriptor ) throw ( ::com::sun::star::uno::RuntimeException, ::com::sun::star::io::IOException, ::com::sun::star::lang::WrappedTargetException );
+ virtual void SAL_CALL recoverFromFile( const ::rtl::OUString& i_SourceLocation, const ::rtl::OUString& i_SalvagedFile, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& i_MediaDescriptor ) throw ( ::com::sun::star::uno::RuntimeException, ::com::sun::star::io::IOException, ::com::sun::star::lang::WrappedTargetException );
+
+ // XTitle
+ virtual ::rtl::OUString SAL_CALL getTitle( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setTitle( const ::rtl::OUString& sTitle ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XTitleChangeBroadcaster
+ virtual void SAL_CALL addTitleChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XTitleChangeListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeTitleChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XTitleChangeListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XUntitledNumbers
+ virtual ::sal_Int32 SAL_CALL leaseNumber( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xComponent ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL releaseNumber( ::sal_Int32 nNumber ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL releaseNumberForComponent( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xComponent ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getUntitledPrefix( ) throw (::com::sun::star::uno::RuntimeException);
+
+ /** clears the given object container
+
+ Clearing is done via disposal - the method calls XComponent::dispose at the given object,
+ which must be one of our impl's or our object containers (m_xForms, m_xReports,
+ m_xTableDefinitions, m_xCommandDefinitions)
+
+ @param _rxContainer
+ the container to clear
+ */
+ static void clearObjectContainer(
+ ::com::sun::star::uno::WeakReference< ::com::sun::star::container::XNameAccess >& _rxContainer);
+
+ /** checks whether the component is already initialized, throws a NotInitializedException if not
+ */
+ inline void checkInitialized() const
+ {
+ if ( !impl_isInitialized() )
+ throw ::com::sun::star::lang::NotInitializedException( ::rtl::OUString(), getThis() );
+ }
+
+ /** checks the document is currently in the initialization phase, or already initialized.
+ Throws NotInitializedException if not so.
+ */
+ inline void checkNotUninitilized() const
+ {
+ if ( impl_isInitialized() || impl_isInitializing() )
+ // fine
+ return;
+
+ throw ::com::sun::star::lang::NotInitializedException( ::rtl::OUString(), getThis() );
+ }
+
+ /** checks whether the document is currently being initialized, or already initialized,
+ throws a DoubleInitializationException if so
+ */
+ inline void checkNotInitialized() const
+ {
+ if ( impl_isInitializing() || impl_isInitialized() )
+ throw ::com::sun::star::frame::DoubleInitializationException( ::rtl::OUString(), getThis() );
+ }
+
+private:
+ /** returns whether the model is currently being initialized
+ */
+ bool impl_isInitializing() const { return m_eInitState == Initializing; }
+
+ /** returns whether the model is already initialized, i.e. the XModel's "initNew" or "load" methods have been called
+ */
+ bool impl_isInitialized() const { return m_eInitState == Initialized; }
+
+ /// tells the model it is being initialized now
+ void impl_setInitializing() { m_eInitState = Initializing; }
+
+ /// tells the model its initialization is done
+ void impl_setInitialized();
+
+ /** closes the frames of all connected controllers
+
+ @param _bDeliverOwnership
+ determines if the ownership should be transfered to the component which
+ possibly vetos the closing
+
+ @raises ::com::sun::star::util::CloseVetoException
+ if the closing was vetoed by any instance
+ */
+ void impl_closeControllerFrames_nolck_throw( sal_Bool _bDeliverOwnership );
+
+ /** disposes the frames of all controllers which are still left in m_aControllers.
+ */
+ void impl_disposeControllerFrames_nothrow();
+
+ /** does a reparenting at the given object container to ourself
+
+ Calls XChild::setParent at the given object, which must be one of our impl's or our
+ object containers (m_xForms, m_xReports, m_xTableDefinitions, m_xCommandDefinitions)
+ */
+ void impl_reparent_nothrow( const ::com::sun::star::uno::WeakReference< ::com::sun::star::container::XNameAccess >& _rxContainer );
+
+ /** retrieves the forms or reports contained, creates and initializes it, if necessary
+
+ @raises DisposedException
+ if the instance is already disposed
+ @raises IllegalArgumentException
+ if <arg>_eType</arg> is not ODatabaseModelImpl::E_FORM and not ODatabaseModelImpl::E_REPORT
+ */
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >
+ impl_getDocumentContainer_throw( ODatabaseModelImpl::ObjectType _eType );
+
+ /** resets everything
+
+ @precond
+ m_pImpl is not <NULLL/>
+ */
+ void
+ impl_reset_nothrow();
+
+ /** imports the document from the given resource.
+ */
+ static void
+ impl_import_nolck_throw(
+ const ::comphelper::ComponentContext _rContext,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxTargetComponent,
+ const ::comphelper::NamedValueCollection& _rResource
+ );
+
+ /** creates a storage for the given URL, truncating it if a file with this name already exists
+
+ @throws Exception
+ if creating the storage failed
+
+ @return
+ the newly created storage for the file at the given URL
+ */
+ ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >
+ impl_createStorageFor_throw(
+ const ::rtl::OUString& _rURL
+ ) const;
+
+ /** sets our "modified" flag
+
+ will notify all our respective listeners, if the "modified" state actually changed
+
+ @param _bModified
+ the (new) flag indicating whether the document is currently modified or not
+ @param _rGuard
+ the guard for our instance. At method entry, the guard must hold the lock. At the moment
+ of method leave, the lock will be released.
+ @precond
+ our mutex is locked
+ @postcond
+ our mutex is not locked
+ */
+ void impl_setModified_nothrow( sal_Bool _bModified, DocumentGuard& _rGuard );
+
+ /** stores the document to the given storage
+
+ Note that the document is actually not rebased to this storage, it just stores a copy of itself
+ to the given target storage.
+
+ @param _rxTargetStorage
+ denotes the storage to store the document into
+ @param _rMediaDescriptor
+ contains additional parameters for storing the document
+ @param _rDocGuard
+ a guard which holds the (only) lock to the document, and which will be temporarily
+ released where necessary (e.g. for notifications, or calling into other components)
+
+ @throws ::com::sun::star::uno::IllegalArgumentException
+ if the given storage is <NULL/>.
+
+ @throws ::com::sun::star::uno::RuntimeException
+ when any of the used operations throws it
+
+ @throws ::com::sun::star::io::IOException
+ when any of the used operations throws it, or any other exception occurs which is no
+ RuntimeException and no IOException
+ */
+ void impl_storeToStorage_throw(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& _rxTargetStorage,
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& _rMediaDescriptor,
+ DocumentGuard& _rDocGuard
+ ) const;
+
+
+ /** impl-version of attachResource
+
+ @param i_rLogicalDocumentURL
+ denotes the logical URL of the document, to be reported by getURL/getLocation
+ @param i_rMediaDescriptor
+ denotes additional document parameters
+ @param _rDocGuard
+ is the guard which currently protects the document instance
+ */
+ sal_Bool impl_attachResource(
+ const ::rtl::OUString& i_rLogicalDocumentURL,
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& i_rMediaDescriptor,
+ DocumentGuard& _rDocGuard
+ );
+
+ /** throws an IOException with the message as defined in the RID_STR_ERROR_WHILE_SAVING resource, wrapping
+ the given caught non-IOException error
+ */
+ void impl_throwIOExceptionCausedBySave_throw(
+ const ::com::sun::star::uno::Any& i_rError,
+ const ::rtl::OUString& i_rTargetURL
+ ) const;
+};
+
+/** an extended version of the ModelMethodGuard, which also cares for the initialization state
+ of the document
+*/
+class DocumentGuard : private ModelMethodGuard
+{
+public:
+ enum MethodType
+ {
+ // a method which is to initialize the document
+ InitMethod,
+ // a default method
+ DefaultMethod,
+ // a method which is used (externally) during the initialization phase
+ MethodUsedDuringInit,
+ // a method which does not need initialization - use with care!
+ MethodWithoutInit
+ };
+
+ /** constructs the guard
+
+ @param _document
+ the ODatabaseDocument instance
+
+ @throws ::com::sun::star::lang::DisposedException
+ If the given component is already disposed
+
+ @throws ::com::sun::star::frame::DoubleInitializationException
+ if _eType is InitMethod, and the given component is already initialized, or currently being initialized.
+
+ @throws ::com::sun::star::lang::NotInitializedException
+ if _eType is DefaultMethod, and the given component is not yet initialized; or if _eType
+ is MethodUsedDuringInit, and the component is still uninitialized, and not in the initialization
+ phase currently.
+ */
+ DocumentGuard( const ODatabaseDocument& _document, MethodType _eType = DefaultMethod )
+ :ModelMethodGuard( _document )
+ ,m_document( _document )
+ {
+ switch ( _eType )
+ {
+ case InitMethod: m_document.checkNotInitialized(); break;
+ case DefaultMethod: m_document.checkInitialized(); break;
+ case MethodUsedDuringInit: m_document.checkNotUninitilized(); break;
+ case MethodWithoutInit: break;
+ }
+ }
+
+ ~DocumentGuard()
+ {
+ }
+
+ void clear()
+ {
+ ModelMethodGuard::clear();
+ }
+ void reset()
+ {
+ ModelMethodGuard::reset();
+ m_document.checkDisposed();
+ }
+
+private:
+
+ const ODatabaseDocument& m_document;
+};
+
+} // namespace dbaccess
+#endif // _DBA_COREDATAACCESS_DATABASEDOCUMENT_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/databaseregistrations.cxx b/dbaccess/source/core/dataaccess/databaseregistrations.cxx
new file mode 100644
index 000000000000..83b6d482b769
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/databaseregistrations.cxx
@@ -0,0 +1,377 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ * 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
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/databaseregistrations.hxx b/dbaccess/source/core/dataaccess/databaseregistrations.hxx
new file mode 100644
index 000000000000..f3213dba6823
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/databaseregistrations.hxx
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ * 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.
+ *
+************************************************************************/
+
+#ifndef OOO_DATASOURCEREGISTRATIONS_HXX
+#define OOO_DATASOURCEREGISTRATIONS_HXX
+
+/** === begin UNO includes === **/
+#include <com/sun/star/uno/XAggregation.hpp>
+/** === end UNO includes === **/
+
+namespace comphelper
+{
+ class ComponentContext;
+}
+
+namespace dbaccess
+{
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XAggregation >
+ createDataSourceRegistrations( const ::comphelper::ComponentContext& _rxContext );
+
+} // namespace dbaccess
+
+#endif // OOO_DATASOURCEREGISTRATIONS_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/datasource.cxx b/dbaccess/source/core/dataaccess/datasource.cxx
new file mode 100644
index 000000000000..4577ebb077e9
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/datasource.cxx
@@ -0,0 +1,1418 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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"
+
+#include "datasource.hxx"
+#include "module_dba.hxx"
+#include "userinformation.hxx"
+#include "commandcontainer.hxx"
+#include "dbastrings.hrc"
+#include "core_resource.hxx"
+#include "core_resource.hrc"
+#include "connection.hxx"
+#include "SharedConnection.hxx"
+#include "databasedocument.hxx"
+#include "OAuthenticationContinuation.hxx"
+
+
+/** === begin UNO includes === **/
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertyState.hpp>
+#include <com/sun/star/beans/XPropertyContainer.hpp>
+#include <com/sun/star/document/XDocumentSubStorageSupplier.hpp>
+#include <com/sun/star/document/XEventBroadcaster.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/reflection/XProxyFactory.hpp>
+#include <com/sun/star/sdbc/XDriverAccess.hpp>
+#include <com/sun/star/sdbc/XDriverManager.hpp>
+#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
+#include <com/sun/star/ucb/AuthenticationRequest.hpp>
+#include <com/sun/star/ucb/XInteractionSupplyAuthentication.hpp>
+#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/view/XPrintable.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/extract.hxx>
+#include <comphelper/guarding.hxx>
+#include <comphelper/interaction.hxx>
+#include <comphelper/namedvaluecollection.hxx>
+#include <comphelper/property.hxx>
+#include <comphelper/seqstream.hxx>
+#include <comphelper/sequence.hxx>
+#include <comphelper/string.hxx>
+#include <connectivity/dbexception.hxx>
+#include <connectivity/dbtools.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+#include <tools/urlobj.hxx>
+#include <typelib/typedescription.hxx>
+#include <unotools/confignode.hxx>
+#include <unotools/sharedunocomponent.hxx>
+#include <rtl/logfile.hxx>
+#include <rtl/digest.h>
+#include <algorithm>
+
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::embed;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::task;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::reflection;
+using namespace ::cppu;
+using namespace ::osl;
+using namespace ::dbtools;
+using namespace ::comphelper;
+namespace css = ::com::sun::star;
+
+namespace dbaccess
+{
+
+//============================================================
+//= FlushNotificationAdapter
+//============================================================
+typedef ::cppu::WeakImplHelper1< XFlushListener > FlushNotificationAdapter_Base;
+/** helper class which implements a XFlushListener, and forwards all
+ notification events to another XFlushListener
+
+ The speciality is that the foreign XFlushListener instance, to which
+ the notifications are forwarded, is held weak.
+
+ Thus, the class can be used with XFlushable instance which hold
+ their listeners with a hard reference, if you simply do not *want*
+ to be held hard-ref-wise.
+*/
+class FlushNotificationAdapter : public FlushNotificationAdapter_Base
+{
+private:
+ WeakReference< XFlushable > m_aBroadcaster;
+ WeakReference< XFlushListener > m_aListener;
+
+public:
+ static void installAdapter( const Reference< XFlushable >& _rxBroadcaster, const Reference< XFlushListener >& _rxListener )
+ {
+ Reference< XFlushListener > xAdapter( new FlushNotificationAdapter( _rxBroadcaster, _rxListener ) );
+ }
+
+protected:
+ FlushNotificationAdapter( const Reference< XFlushable >& _rxBroadcaster, const Reference< XFlushListener >& _rxListener );
+ ~FlushNotificationAdapter();
+
+ void SAL_CALL impl_dispose( bool _bRevokeListener );
+
+protected:
+ // XFlushListener
+ virtual void SAL_CALL flushed( const ::com::sun::star::lang::EventObject& rEvent ) throw (::com::sun::star::uno::RuntimeException);
+ // XEventListener
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);
+};
+
+//------------------------------------------------------------
+DBG_NAME( FlushNotificationAdapter )
+//------------------------------------------------------------
+FlushNotificationAdapter::FlushNotificationAdapter( const Reference< XFlushable >& _rxBroadcaster, const Reference< XFlushListener >& _rxListener )
+ :m_aBroadcaster( _rxBroadcaster )
+ ,m_aListener( _rxListener )
+{
+ DBG_CTOR( FlushNotificationAdapter, NULL );
+ DBG_ASSERT( _rxBroadcaster.is(), "FlushNotificationAdapter::FlushNotificationAdapter: invalid flushable!" );
+
+ osl_incrementInterlockedCount( &m_refCount );
+ {
+ if ( _rxBroadcaster.is() )
+ _rxBroadcaster->addFlushListener( this );
+ }
+ osl_decrementInterlockedCount( &m_refCount );
+ DBG_ASSERT( m_refCount == 1, "FlushNotificationAdapter::FlushNotificationAdapter: broadcaster isn't holding by hard ref!?" );
+}
+
+//------------------------------------------------------------
+FlushNotificationAdapter::~FlushNotificationAdapter()
+{
+ DBG_DTOR( FlushNotificationAdapter, NULL );
+}
+
+void SAL_CALL FlushNotificationAdapter::impl_dispose( bool _bRevokeListener )
+{
+ Reference< XFlushListener > xKeepAlive( this );
+
+ if ( _bRevokeListener )
+ {
+ Reference< XFlushable > xFlushable( m_aBroadcaster );
+ if ( xFlushable.is() )
+ xFlushable->removeFlushListener( this );
+ }
+
+ m_aListener = Reference< XFlushListener >();
+ m_aBroadcaster = Reference< XFlushable >();
+}
+
+void SAL_CALL FlushNotificationAdapter::flushed( const EventObject& rEvent ) throw (RuntimeException)
+{
+ Reference< XFlushListener > xListener( m_aListener );
+ if ( xListener.is() )
+ xListener->flushed( rEvent );
+ else
+ impl_dispose( true );
+}
+
+void SAL_CALL FlushNotificationAdapter::disposing( const EventObject& Source ) throw (RuntimeException)
+{
+ Reference< XFlushListener > xListener( m_aListener );
+ if ( xListener.is() )
+ xListener->disposing( Source );
+
+ impl_dispose( false );
+}
+
+OAuthenticationContinuation::OAuthenticationContinuation()
+ :m_bRemberPassword(sal_True), // TODO: a meaningfull default
+ m_bCanSetUserName(sal_True)
+{
+}
+
+sal_Bool SAL_CALL OAuthenticationContinuation::canSetRealm( ) throw(RuntimeException)
+{
+ return sal_False;
+}
+
+void SAL_CALL OAuthenticationContinuation::setRealm( const ::rtl::OUString& /*Realm*/ ) throw(RuntimeException)
+{
+ DBG_ERROR("OAuthenticationContinuation::setRealm: not supported!");
+}
+
+sal_Bool SAL_CALL OAuthenticationContinuation::canSetUserName( ) throw(RuntimeException)
+{
+ // we alwas allow this, even if the database document is read-only. In this case,
+ // it's simply that the user cannot store the new user name.
+ return m_bCanSetUserName;
+}
+
+void SAL_CALL OAuthenticationContinuation::setUserName( const ::rtl::OUString& _rUser ) throw(RuntimeException)
+{
+ m_sUser = _rUser;
+}
+
+sal_Bool SAL_CALL OAuthenticationContinuation::canSetPassword( ) throw(RuntimeException)
+{
+ return sal_True;
+}
+
+void SAL_CALL OAuthenticationContinuation::setPassword( const ::rtl::OUString& _rPassword ) throw(RuntimeException)
+{
+ m_sPassword = _rPassword;
+}
+
+Sequence< RememberAuthentication > SAL_CALL OAuthenticationContinuation::getRememberPasswordModes( RememberAuthentication& _reDefault ) throw(RuntimeException)
+{
+ Sequence< RememberAuthentication > aReturn(1);
+ _reDefault = aReturn[0] = RememberAuthentication_SESSION;
+ return aReturn;
+}
+
+void SAL_CALL OAuthenticationContinuation::setRememberPassword( RememberAuthentication _eRemember ) throw(RuntimeException)
+{
+ m_bRemberPassword = (RememberAuthentication_NO != _eRemember);
+}
+
+sal_Bool SAL_CALL OAuthenticationContinuation::canSetAccount( ) throw(RuntimeException)
+{
+ return sal_False;
+}
+
+void SAL_CALL OAuthenticationContinuation::setAccount( const ::rtl::OUString& ) throw(RuntimeException)
+{
+ DBG_ERROR("OAuthenticationContinuation::setAccount: not supported!");
+}
+
+Sequence< RememberAuthentication > SAL_CALL OAuthenticationContinuation::getRememberAccountModes( RememberAuthentication& _reDefault ) throw(RuntimeException)
+{
+ Sequence < RememberAuthentication > aReturn(1);
+ aReturn[0] = RememberAuthentication_NO;
+ _reDefault = RememberAuthentication_NO;
+ return aReturn;
+}
+
+void SAL_CALL OAuthenticationContinuation::setRememberAccount( RememberAuthentication /*Remember*/ ) throw(RuntimeException)
+{
+ DBG_ERROR("OAuthenticationContinuation::setRememberAccount: not supported!");
+}
+
+/** The class OSharedConnectionManager implements a structure to share connections.
+ It owns the master connections which will be disposed when the last connection proxy is gone.
+*/
+typedef ::cppu::WeakImplHelper1< XEventListener > OConnectionHelper_BASE;
+// need to hold the digest
+struct TDigestHolder
+{
+ sal_uInt8 m_pBuffer[RTL_DIGEST_LENGTH_SHA1];
+ TDigestHolder()
+ {
+ m_pBuffer[0] = 0;
+ }
+
+};
+
+class OSharedConnectionManager : public OConnectionHelper_BASE
+{
+
+ // contains the currently used master connections
+ typedef struct
+ {
+ Reference< XConnection > xMasterConnection;
+ oslInterlockedCount nALiveCount;
+ } TConnectionHolder;
+
+ // the less-compare functor, used for the stl::map
+ struct TDigestLess : public ::std::binary_function< TDigestHolder, TDigestHolder, bool>
+ {
+ bool operator() (const TDigestHolder& x, const TDigestHolder& y) const
+ {
+ sal_uInt32 i;
+ for(i=0;i < RTL_DIGEST_LENGTH_SHA1 && (x.m_pBuffer[i] >= y.m_pBuffer[i]); ++i)
+ ;
+ return i < RTL_DIGEST_LENGTH_SHA1;
+ }
+ };
+
+ typedef ::std::map< TDigestHolder,TConnectionHolder,TDigestLess> TConnectionMap; // holds the master connections
+ typedef ::std::map< Reference< XConnection >,TConnectionMap::iterator> TSharedConnectionMap;// holds the shared connections
+
+ ::osl::Mutex m_aMutex;
+ TConnectionMap m_aConnections; // remeber the master connection in conjunction with the digest
+ TSharedConnectionMap m_aSharedConnection; // the shared connections with conjunction with an iterator into the connections map
+ Reference< XProxyFactory > m_xProxyFactory;
+
+protected:
+ ~OSharedConnectionManager();
+
+public:
+ OSharedConnectionManager(const Reference< XMultiServiceFactory >& _rxServiceFactory);
+
+ void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw(RuntimeException);
+ Reference<XConnection> getConnection( const rtl::OUString& url,
+ const rtl::OUString& user,
+ const rtl::OUString& password,
+ const Sequence< PropertyValue >& _aInfo,
+ ODatabaseSource* _pDataSource);
+ void addEventListener(const Reference<XConnection>& _rxConnection,TConnectionMap::iterator& _rIter);
+};
+
+DBG_NAME(OSharedConnectionManager)
+OSharedConnectionManager::OSharedConnectionManager(const Reference< XMultiServiceFactory >& _rxServiceFactory)
+{
+ DBG_CTOR(OSharedConnectionManager,NULL);
+ m_xProxyFactory.set(_rxServiceFactory->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.reflection.ProxyFactory"))),UNO_QUERY);
+}
+
+OSharedConnectionManager::~OSharedConnectionManager()
+{
+ DBG_DTOR(OSharedConnectionManager,NULL);
+}
+
+void SAL_CALL OSharedConnectionManager::disposing( const ::com::sun::star::lang::EventObject& Source ) throw(RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ Reference<XConnection> xConnection(Source.Source,UNO_QUERY);
+ TSharedConnectionMap::iterator aFind = m_aSharedConnection.find(xConnection);
+ if ( m_aSharedConnection.end() != aFind )
+ {
+ osl_decrementInterlockedCount(&aFind->second->second.nALiveCount);
+ if ( !aFind->second->second.nALiveCount )
+ {
+ ::comphelper::disposeComponent(aFind->second->second.xMasterConnection);
+ m_aConnections.erase(aFind->second);
+ }
+ m_aSharedConnection.erase(aFind);
+ }
+}
+
+Reference<XConnection> OSharedConnectionManager::getConnection( const rtl::OUString& url,
+ const rtl::OUString& user,
+ const rtl::OUString& password,
+ const Sequence< PropertyValue >& _aInfo,
+ ODatabaseSource* _pDataSource)
+{
+ MutexGuard aGuard(m_aMutex);
+ TConnectionMap::key_type nId;
+ Sequence< PropertyValue > aInfoCopy(_aInfo);
+ sal_Int32 nPos = aInfoCopy.getLength();
+ aInfoCopy.realloc( nPos + 2 );
+ aInfoCopy[nPos].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TableFilter"));
+ aInfoCopy[nPos++].Value <<= _pDataSource->m_pImpl->m_aTableFilter;
+ aInfoCopy[nPos].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TableTypeFilter"));
+ aInfoCopy[nPos++].Value <<= _pDataSource->m_pImpl->m_aTableTypeFilter; // #22377# OJ
+
+ ::rtl::OUString sUser = user;
+ ::rtl::OUString sPassword = password;
+ if ((0 == sUser.getLength()) && (0 == sPassword.getLength()) && (0 != _pDataSource->m_pImpl->m_sUser.getLength()))
+ { // ease the usage of this method. data source which are intended to have a user automatically
+ // fill in the user/password combination if the caller of this method does not specify otherwise
+ // 86951 - 05/08/2001 - frank.schoenheit@germany.sun.com
+ sUser = _pDataSource->m_pImpl->m_sUser;
+ if (0 != _pDataSource->m_pImpl->m_aPassword.getLength())
+ sPassword = _pDataSource->m_pImpl->m_aPassword;
+ }
+
+ ::connectivity::OConnectionWrapper::createUniqueId(url,aInfoCopy,nId.m_pBuffer,sUser,sPassword);
+ TConnectionMap::iterator aIter = m_aConnections.find(nId);
+
+ if ( m_aConnections.end() == aIter )
+ {
+ TConnectionHolder aHolder;
+ aHolder.nALiveCount = 0; // will be incremented by addListener
+ aHolder.xMasterConnection = _pDataSource->buildIsolatedConnection(user,password);
+ aIter = m_aConnections.insert(TConnectionMap::value_type(nId,aHolder)).first;
+ }
+
+ Reference<XConnection> xRet;
+ if ( aIter->second.xMasterConnection.is() )
+ {
+ Reference< XAggregation > xConProxy = m_xProxyFactory->createProxy(aIter->second.xMasterConnection.get());
+ xRet = new OSharedConnection(xConProxy);
+ m_aSharedConnection.insert(TSharedConnectionMap::value_type(xRet,aIter));
+ addEventListener(xRet,aIter);
+ }
+
+ return xRet;
+}
+void OSharedConnectionManager::addEventListener(const Reference<XConnection>& _rxConnection,TConnectionMap::iterator& _rIter)
+{
+ Reference<XComponent> xComp(_rxConnection,UNO_QUERY);
+ xComp->addEventListener(this);
+ OSL_ENSURE( m_aConnections.end() != _rIter , "Iterator is end!");
+ osl_incrementInterlockedCount(&_rIter->second.nALiveCount);
+}
+
+namespace
+{
+ Sequence< PropertyValue > lcl_filterDriverProperties( const Reference< XDriver >& _xDriver, const ::rtl::OUString& _sUrl,
+ const Sequence< PropertyValue >& _rDataSourceSettings, const AsciiPropertyValue* _pKnownSettings )
+ {
+ if ( _xDriver.is() )
+ {
+ Sequence< DriverPropertyInfo > aDriverInfo(_xDriver->getPropertyInfo(_sUrl,_rDataSourceSettings));
+
+ const PropertyValue* pDataSourceSetting = _rDataSourceSettings.getConstArray();
+ const PropertyValue* pEnd = pDataSourceSetting + _rDataSourceSettings.getLength();
+
+ ::std::vector< PropertyValue > aRet;
+
+ for ( ; pDataSourceSetting != pEnd ; ++pDataSourceSetting )
+ {
+ sal_Bool bAllowSetting = sal_False;
+ const AsciiPropertyValue* pSetting = _pKnownSettings;
+ for ( ; pSetting->AsciiName; ++pSetting )
+ {
+ if ( !pDataSourceSetting->Name.compareToAscii( pSetting->AsciiName ) )
+ { // the particular data source setting is known
+
+ const DriverPropertyInfo* pAllowedDriverSetting = aDriverInfo.getConstArray();
+ const DriverPropertyInfo* pDriverSettingsEnd = pAllowedDriverSetting + aDriverInfo.getLength();
+ for ( ; pAllowedDriverSetting != pDriverSettingsEnd; ++pAllowedDriverSetting )
+ {
+ if ( !pAllowedDriverSetting->Name.compareToAscii( pSetting->AsciiName ) )
+ { // the driver also allows this setting
+ bAllowSetting = sal_True;
+ break;
+ }
+ }
+ break;
+ }
+ }
+ if ( bAllowSetting || !pSetting->AsciiName )
+ { // if the driver allows this particular setting, or if the setting is completely unknown,
+ // we pass it to the driver
+ aRet.push_back( *pDataSourceSetting );
+ }
+ }
+ if ( !aRet.empty() )
+ return Sequence< PropertyValue >(&(*aRet.begin()),aRet.size());
+ }
+ return Sequence< PropertyValue >();
+ }
+
+ typedef ::std::map< ::rtl::OUString, sal_Int32 > PropertyAttributeCache;
+
+ struct IsDefaultAndNotRemoveable : public ::std::unary_function< PropertyValue, bool >
+ {
+ private:
+ const PropertyAttributeCache& m_rAttribs;
+
+ public:
+ IsDefaultAndNotRemoveable( const PropertyAttributeCache& _rAttribs ) : m_rAttribs( _rAttribs ) { }
+
+ bool operator()( const PropertyValue& _rProp )
+ {
+ if ( _rProp.State != PropertyState_DEFAULT_VALUE )
+ return false;
+
+ bool bRemoveable = true;
+
+ PropertyAttributeCache::const_iterator pos = m_rAttribs.find( _rProp.Name );
+ OSL_ENSURE( pos != m_rAttribs.end(), "IsDefaultAndNotRemoveable: illegal property name!" );
+ if ( pos != m_rAttribs.end() )
+ bRemoveable = ( ( pos->second & PropertyAttribute::REMOVEABLE ) != 0 );
+
+ return !bRemoveable;
+ }
+ };
+}
+//============================================================
+//= ODatabaseContext
+//============================================================
+DBG_NAME(ODatabaseSource)
+
+extern "C" void SAL_CALL createRegistryInfo_ODatabaseSource()
+{
+ static ::dba::OAutoRegistration< ODatabaseSource > aAutoRegistration;
+}
+
+ODatabaseSource::ODatabaseSource(const ::rtl::Reference<ODatabaseModelImpl>& _pImpl)
+ :ModelDependentComponent( _pImpl )
+ ,ODatabaseSource_Base( getMutex() )
+ ,OPropertySetHelper( ODatabaseSource_Base::rBHelper )
+ ,m_aBookmarks( *this, getMutex() )
+ ,m_aFlushListeners( getMutex() )
+{
+ // some kind of default
+ DBG_CTOR(ODatabaseSource,NULL);
+ OSL_TRACE( "DS: ctor: %p: %p", this, m_pImpl.get() );
+}
+
+ODatabaseSource::~ODatabaseSource()
+{
+ OSL_TRACE( "DS: dtor: %p: %p", this, m_pImpl.get() );
+ DBG_DTOR(ODatabaseSource,NULL);
+ if ( !ODatabaseSource_Base::rBHelper.bInDispose && !ODatabaseSource_Base::rBHelper.bDisposed )
+ {
+ acquire();
+ dispose();
+ }
+}
+
+void ODatabaseSource::setName( const Reference< XDocumentDataSource >& _rxDocument, const ::rtl::OUString& _rNewName, DBContextAccess )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::setName" );
+ ODatabaseSource& rModelImpl = dynamic_cast< ODatabaseSource& >( *_rxDocument.get() );
+
+ ::osl::MutexGuard aGuard( rModelImpl.m_aMutex );
+ if ( rModelImpl.m_pImpl.is() )
+ rModelImpl.m_pImpl->m_sName = _rNewName;
+}
+
+// com::sun::star::lang::XTypeProvider
+Sequence< Type > ODatabaseSource::getTypes() throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::getTypes" );
+ OTypeCollection aPropertyHelperTypes( ::getCppuType( (const Reference< XFastPropertySet > *)0 ),
+ ::getCppuType( (const Reference< XPropertySet > *)0 ),
+ ::getCppuType( (const Reference< XMultiPropertySet > *)0 ));
+
+ return ::comphelper::concatSequences(
+ ODatabaseSource_Base::getTypes(),
+ aPropertyHelperTypes.getTypes()
+ );
+}
+
+Sequence< sal_Int8 > ODatabaseSource::getImplementationId() throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::getImplementationId" );
+ static OImplementationId * pId = 0;
+ if (! pId)
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if (! pId)
+ {
+ static OImplementationId aId;
+ pId = &aId;
+ }
+ }
+ return pId->getImplementationId();
+}
+
+// com::sun::star::uno::XInterface
+Any ODatabaseSource::queryInterface( const Type & rType ) throw (RuntimeException)
+{
+ Any aIface = ODatabaseSource_Base::queryInterface( rType );
+ if ( !aIface.hasValue() )
+ aIface = ::cppu::OPropertySetHelper::queryInterface( rType );
+ return aIface;
+}
+
+void ODatabaseSource::acquire() throw ()
+{
+ ODatabaseSource_Base::acquire();
+}
+
+void ODatabaseSource::release() throw ()
+{
+ ODatabaseSource_Base::release();
+}
+
+void SAL_CALL ODatabaseSource::disposing( const ::com::sun::star::lang::EventObject& Source ) throw(RuntimeException)
+{
+ if ( m_pImpl.is() )
+ m_pImpl->disposing(Source);
+}
+// XServiceInfo
+rtl::OUString ODatabaseSource::getImplementationName( ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::getImplementationName" );
+ return getImplementationName_static();
+}
+
+rtl::OUString ODatabaseSource::getImplementationName_static( ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::getImplementationName_static" );
+ return rtl::OUString::createFromAscii("com.sun.star.comp.dba.ODatabaseSource");
+}
+
+Sequence< ::rtl::OUString > ODatabaseSource::getSupportedServiceNames( ) throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::getSupportedServiceNames" );
+ return getSupportedServiceNames_static();
+}
+
+Reference< XInterface > ODatabaseSource::Create( const Reference< XComponentContext >& _rxContext )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::Create" );
+ ::comphelper::ComponentContext aContext( _rxContext );
+ Reference< XSingleServiceFactory > xDBContext( aContext.createComponent( (::rtl::OUString)SERVICE_SDB_DATABASECONTEXT ), UNO_QUERY_THROW );
+ return xDBContext->createInstance();
+}
+
+Sequence< ::rtl::OUString > ODatabaseSource::getSupportedServiceNames_static( ) throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::getSupportedServiceNames_static" );
+ Sequence< ::rtl::OUString > aSNS( 2 );
+ aSNS[0] = SERVICE_SDB_DATASOURCE;
+ aSNS[1] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdb.DocumentDataSource"));
+ return aSNS;
+}
+
+sal_Bool ODatabaseSource::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::supportsService" );
+ return ::comphelper::findValue(getSupportedServiceNames(), _rServiceName, sal_True).getLength() != 0;
+}
+
+// OComponentHelper
+void ODatabaseSource::disposing()
+{
+ OSL_TRACE( "DS: disp: %p, %p", this, m_pImpl.get() );
+ ODatabaseSource_Base::WeakComponentImplHelperBase::disposing();
+ OPropertySetHelper::disposing();
+
+ EventObject aDisposeEvent(static_cast<XWeak*>(this));
+ m_aFlushListeners.disposeAndClear( aDisposeEvent );
+
+ ODatabaseDocument::clearObjectContainer(m_pImpl->m_xCommandDefinitions);
+ ODatabaseDocument::clearObjectContainer(m_pImpl->m_xTableDefinitions);
+ m_pImpl.clear();
+}
+
+Reference< XConnection > ODatabaseSource::buildLowLevelConnection(const ::rtl::OUString& _rUid, const ::rtl::OUString& _rPwd)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::buildLowLevelConnection" );
+ Reference< XConnection > xReturn;
+
+ Reference< XDriverManager > xManager;
+ if ( !m_pImpl->m_aContext.createComponent( "com.sun.star.sdbc.ConnectionPool", xManager ) )
+ // no connection pool installed, fall back to driver manager
+ m_pImpl->m_aContext.createComponent( "com.sun.star.sdbc.DriverManager", xManager );
+
+ ::rtl::OUString sUser(_rUid);
+ ::rtl::OUString sPwd(_rPwd);
+ if ((0 == sUser.getLength()) && (0 == sPwd.getLength()) && (0 != m_pImpl->m_sUser.getLength()))
+ { // ease the usage of this method. data source which are intended to have a user automatically
+ // fill in the user/password combination if the caller of this method does not specify otherwise
+ sUser = m_pImpl->m_sUser;
+ if (0 != m_pImpl->m_aPassword.getLength())
+ sPwd = m_pImpl->m_aPassword;
+ }
+
+ sal_uInt16 nExceptionMessageId = RID_STR_COULDNOTCONNECT_UNSPECIFIED;
+ if (xManager.is())
+ {
+ sal_Int32 nAdditionalArgs(0);
+ if (sUser.getLength()) ++nAdditionalArgs;
+ if (sPwd.getLength()) ++nAdditionalArgs;
+
+ Sequence< PropertyValue > aUserPwd(nAdditionalArgs);
+ sal_Int32 nArgPos = 0;
+ if (sUser.getLength())
+ {
+ aUserPwd[ nArgPos ].Name = ::rtl::OUString::createFromAscii("user");
+ aUserPwd[ nArgPos ].Value <<= sUser;
+ ++nArgPos;
+ }
+ if (sPwd.getLength())
+ {
+ aUserPwd[ nArgPos ].Name = ::rtl::OUString::createFromAscii("password");
+ aUserPwd[ nArgPos ].Value <<= sPwd;
+ }
+ Reference< XDriver > xDriver;
+ try
+ {
+ Reference< XDriverAccess > xAccessDrivers( xManager, UNO_QUERY );
+ if ( xAccessDrivers.is() )
+ xDriver = xAccessDrivers->getDriverByURL( m_pImpl->m_sConnectURL );
+ }
+ catch( const Exception& )
+ {
+ DBG_ERROR( "ODatabaseSource::buildLowLevelConnection: got a strange exception while analyzing the error!" );
+ }
+ if ( !xDriver.is() || !xDriver->acceptsURL( m_pImpl->m_sConnectURL ) )
+ {
+ // Nowadays, it's allowed for a driver to be registered for a given URL, but actually not to accept it.
+ // This is because registration nowadays happens at compile time (by adding respective configuration data),
+ // but acceptance is decided at runtime.
+ nExceptionMessageId = RID_STR_COULDNOTCONNECT_NODRIVER;
+ }
+ else
+ {
+ Sequence< PropertyValue > aDriverInfo = lcl_filterDriverProperties(
+ xDriver,
+ m_pImpl->m_sConnectURL,
+ m_pImpl->m_xSettings->getPropertyValues(),
+ m_pImpl->getDefaultDataSourceSettings()
+ );
+
+ if ( m_pImpl->isEmbeddedDatabase() )
+ {
+ sal_Int32 nCount = aDriverInfo.getLength();
+ aDriverInfo.realloc(nCount + 2 );
+ aDriverInfo[nCount].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("URL"));
+ aDriverInfo[nCount++].Value <<= m_pImpl->getURL();
+ aDriverInfo[nCount].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Storage"));
+ Reference< css::document::XDocumentSubStorageSupplier> xDocSup( m_pImpl->getDocumentSubStorageSupplier() );
+ aDriverInfo[nCount++].Value <<= xDocSup->getDocumentSubStorage(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("database")),ElementModes::READWRITE);
+ }
+ if (nAdditionalArgs)
+ xReturn = xManager->getConnectionWithInfo(m_pImpl->m_sConnectURL, ::comphelper::concatSequences(aUserPwd,aDriverInfo));
+ else
+ xReturn = xManager->getConnectionWithInfo(m_pImpl->m_sConnectURL,aDriverInfo);
+
+ if ( m_pImpl->isEmbeddedDatabase() )
+ {
+ // see ODatabaseSource::flushed for comment on why we register as FlushListener
+ // at the connection
+ Reference< XFlushable > xFlushable( xReturn, UNO_QUERY );
+ if ( xFlushable.is() )
+ FlushNotificationAdapter::installAdapter( xFlushable, this );
+ }
+ }
+ }
+ else
+ nExceptionMessageId = RID_STR_COULDNOTLOAD_MANAGER;
+
+ if ( !xReturn.is() )
+ {
+ ::rtl::OUString sMessage = DBACORE_RESSTRING( nExceptionMessageId );
+
+ SQLContext aContext;
+ aContext.Message = DBACORE_RESSTRING( RID_STR_CONNECTION_REQUEST );
+ ::comphelper::string::searchAndReplaceAsciiI( aContext.Message, "$name$", m_pImpl->m_sConnectURL );
+
+ throwGenericSQLException( sMessage, static_cast< XDataSource* >( this ), makeAny( aContext ) );
+ }
+
+ return xReturn;
+}
+
+// OPropertySetHelper
+Reference< XPropertySetInfo > ODatabaseSource::getPropertySetInfo() throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::getPropertySetInfo" );
+ return createPropertySetInfo( getInfoHelper() ) ;
+}
+
+// comphelper::OPropertyArrayUsageHelper
+::cppu::IPropertyArrayHelper* ODatabaseSource::createArrayHelper( ) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::createArrayHelper" );
+ BEGIN_PROPERTY_HELPER(13)
+ DECL_PROP1(INFO, Sequence< PropertyValue >, BOUND);
+ DECL_PROP1_BOOL(ISPASSWORDREQUIRED, BOUND);
+ DECL_PROP1_BOOL(ISREADONLY, READONLY);
+ DECL_PROP1(LAYOUTINFORMATION, Sequence< PropertyValue >, BOUND);
+ DECL_PROP1(NAME, ::rtl::OUString, READONLY);
+ DECL_PROP2_IFACE(NUMBERFORMATSSUPPLIER, XNumberFormatsSupplier, READONLY, TRANSIENT);
+ DECL_PROP1(PASSWORD, ::rtl::OUString, TRANSIENT);
+ DECL_PROP2_IFACE(SETTINGS, XPropertySet, BOUND, READONLY);
+ DECL_PROP1_BOOL(SUPPRESSVERSIONCL, BOUND);
+ DECL_PROP1(TABLEFILTER, Sequence< ::rtl::OUString >,BOUND);
+ DECL_PROP1(TABLETYPEFILTER, Sequence< ::rtl::OUString >,BOUND);
+ DECL_PROP1(URL, ::rtl::OUString, BOUND);
+ DECL_PROP1(USER, ::rtl::OUString, BOUND);
+ END_PROPERTY_HELPER();
+}
+
+// cppu::OPropertySetHelper
+::cppu::IPropertyArrayHelper& ODatabaseSource::getInfoHelper()
+{
+ return *getArrayHelper();
+}
+
+sal_Bool ODatabaseSource::convertFastPropertyValue(Any & rConvertedValue, Any & rOldValue, sal_Int32 nHandle, const Any& rValue ) throw( IllegalArgumentException )
+{
+ sal_Bool bModified(sal_False);
+ if ( m_pImpl.is() )
+ {
+ switch (nHandle)
+ {
+ case PROPERTY_ID_TABLEFILTER:
+ bModified = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, m_pImpl->m_aTableFilter);
+ break;
+ case PROPERTY_ID_TABLETYPEFILTER:
+ bModified = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, m_pImpl->m_aTableTypeFilter);
+ break;
+ case PROPERTY_ID_USER:
+ bModified = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, m_pImpl->m_sUser);
+ break;
+ case PROPERTY_ID_PASSWORD:
+ bModified = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, m_pImpl->m_aPassword);
+ break;
+ case PROPERTY_ID_ISPASSWORDREQUIRED:
+ bModified = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, m_pImpl->m_bPasswordRequired);
+ break;
+ case PROPERTY_ID_SUPPRESSVERSIONCL:
+ bModified = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, m_pImpl->m_bSuppressVersionColumns);
+ break;
+ case PROPERTY_ID_LAYOUTINFORMATION:
+ bModified = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, m_pImpl->m_aLayoutInformation);
+ break;
+ case PROPERTY_ID_URL:
+ {
+ bModified = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, m_pImpl->m_sConnectURL);
+ } break;
+ case PROPERTY_ID_INFO:
+ {
+ Sequence<PropertyValue> aValues;
+ if (!(rValue >>= aValues))
+ throw IllegalArgumentException();
+
+ const PropertyValue* valueEnd = aValues.getConstArray() + aValues.getLength();
+ const PropertyValue* checkName = aValues.getConstArray();
+ for ( ;checkName != valueEnd; ++checkName )
+ {
+ if ( !checkName->Name.getLength() )
+ throw IllegalArgumentException();
+ }
+
+ Sequence< PropertyValue > aSettings = m_pImpl->m_xSettings->getPropertyValues();
+ bModified = aSettings.getLength() != aValues.getLength();
+ if ( !bModified )
+ {
+ const PropertyValue* pInfoIter = aSettings.getConstArray();
+ const PropertyValue* checkValue = aValues.getConstArray();
+ for ( ;!bModified && checkValue != valueEnd ; ++checkValue,++pInfoIter)
+ {
+ bModified = checkValue->Name != pInfoIter->Name;
+ if ( !bModified )
+ {
+ bModified = !::comphelper::compare(checkValue->Value,pInfoIter->Value);
+ }
+ }
+ }
+
+ rConvertedValue = rValue;
+ rOldValue <<= aSettings;
+ }
+ break;
+ default:
+ DBG_ERROR( "ODatabaseSource::convertFastPropertyValue: unknown or readonly Property!" );
+ }
+ }
+ return bModified;
+}
+
+namespace
+{
+ struct SelectPropertyName : public ::std::unary_function< PropertyValue, ::rtl::OUString >
+ {
+ public:
+ const ::rtl::OUString& operator()( const PropertyValue& _lhs )
+ {
+ return _lhs.Name;
+ }
+ };
+
+ /** sets a new set of property values at a given property bag instance
+
+ The methods takes a property bag, and a sequence of property values to set at this bag.
+ Upon return, every property which is not part of the given sequence is
+ <ul><li>removed from the bag, if it's a removeable property</li>
+ <li><em>or</em>reset to its default value, if it's not a removeable property</li>
+ </ul>.
+
+ @param _rxPropertyBag
+ the property bag to operate on
+ @param _rAllNewPropertyValues
+ the new property values to set at the bag
+ */
+ void lcl_setPropertyValues_resetOrRemoveOther( const Reference< XPropertyAccess >& _rxPropertyBag, const Sequence< PropertyValue >& _rAllNewPropertyValues )
+ {
+ // sequences are ugly to operate on
+ typedef ::std::set< ::rtl::OUString > StringSet;
+ StringSet aToBeSetPropertyNames;
+ ::std::transform(
+ _rAllNewPropertyValues.getConstArray(),
+ _rAllNewPropertyValues.getConstArray() + _rAllNewPropertyValues.getLength(),
+ ::std::insert_iterator< StringSet >( aToBeSetPropertyNames, aToBeSetPropertyNames.end() ),
+ SelectPropertyName()
+ );
+
+ try
+ {
+ // obtain all properties currently known at the bag
+ Reference< XPropertySet > xPropertySet( _rxPropertyBag, UNO_QUERY_THROW );
+ Reference< XPropertySetInfo > xPSI( xPropertySet->getPropertySetInfo(), UNO_QUERY_THROW );
+ Sequence< Property > aAllExistentProperties( xPSI->getProperties() );
+
+ Reference< XPropertyState > xPropertyState( _rxPropertyBag, UNO_QUERY_THROW );
+ Reference< XPropertyContainer > xPropertyContainer( _rxPropertyBag, UNO_QUERY_THROW );
+
+ // loop through them, and reset resp. default properties which are not to be set
+ const Property* pExistentProperty( aAllExistentProperties.getConstArray() );
+ const Property* pExistentPropertyEnd( aAllExistentProperties.getConstArray() + aAllExistentProperties.getLength() );
+ for ( ; pExistentProperty != pExistentPropertyEnd; ++pExistentProperty )
+ {
+ if ( aToBeSetPropertyNames.find( pExistentProperty->Name ) != aToBeSetPropertyNames.end() )
+ continue;
+
+ // this property is not to be set, but currently exists in the bag.
+ // -> Remove, respectively default, it
+ if ( ( pExistentProperty->Attributes & PropertyAttribute::REMOVEABLE ) != 0 )
+ xPropertyContainer->removeProperty( pExistentProperty->Name );
+ else
+ xPropertyState->setPropertyToDefault( pExistentProperty->Name );
+ }
+
+ // finally, set the new property values
+ _rxPropertyBag->setPropertyValues( _rAllNewPropertyValues );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+}
+
+void ODatabaseSource::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw (Exception)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::setFastPropertyValue_NoBroadcast" );
+ if ( m_pImpl.is() )
+ {
+ switch(nHandle)
+ {
+ case PROPERTY_ID_TABLEFILTER:
+ rValue >>= m_pImpl->m_aTableFilter;
+ break;
+ case PROPERTY_ID_TABLETYPEFILTER:
+ rValue >>= m_pImpl->m_aTableTypeFilter;
+ break;
+ case PROPERTY_ID_USER:
+ rValue >>= m_pImpl->m_sUser;
+ // if the user name changed, reset the password
+ m_pImpl->m_aPassword = ::rtl::OUString();
+ break;
+ case PROPERTY_ID_PASSWORD:
+ rValue >>= m_pImpl->m_aPassword;
+ break;
+ case PROPERTY_ID_ISPASSWORDREQUIRED:
+ m_pImpl->m_bPasswordRequired = any2bool(rValue);
+ break;
+ case PROPERTY_ID_SUPPRESSVERSIONCL:
+ m_pImpl->m_bSuppressVersionColumns = any2bool(rValue);
+ break;
+ case PROPERTY_ID_URL:
+ rValue >>= m_pImpl->m_sConnectURL;
+ break;
+ case PROPERTY_ID_INFO:
+ {
+ Sequence< PropertyValue > aInfo;
+ OSL_VERIFY( rValue >>= aInfo );
+ lcl_setPropertyValues_resetOrRemoveOther( m_pImpl->m_xSettings, aInfo );
+ }
+ break;
+ case PROPERTY_ID_LAYOUTINFORMATION:
+ rValue >>= m_pImpl->m_aLayoutInformation;
+ break;
+ }
+ m_pImpl->setModified(sal_True);
+ }
+}
+
+void ODatabaseSource::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
+{
+ //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::getFastPropertyValue" );
+ if ( m_pImpl.is() )
+ {
+ switch (nHandle)
+ {
+ case PROPERTY_ID_TABLEFILTER:
+ rValue <<= m_pImpl->m_aTableFilter;
+ break;
+ case PROPERTY_ID_TABLETYPEFILTER:
+ rValue <<= m_pImpl->m_aTableTypeFilter;
+ break;
+ case PROPERTY_ID_USER:
+ rValue <<= m_pImpl->m_sUser;
+ break;
+ case PROPERTY_ID_PASSWORD:
+ rValue <<= m_pImpl->m_aPassword;
+ break;
+ case PROPERTY_ID_ISPASSWORDREQUIRED:
+ rValue = bool2any(m_pImpl->m_bPasswordRequired);
+ break;
+ case PROPERTY_ID_SUPPRESSVERSIONCL:
+ rValue = bool2any(m_pImpl->m_bSuppressVersionColumns);
+ break;
+ case PROPERTY_ID_ISREADONLY:
+ rValue = bool2any(m_pImpl->m_bReadOnly);
+ break;
+ case PROPERTY_ID_INFO:
+ {
+ try
+ {
+ // collect the property attributes of all current settings
+ Reference< XPropertySet > xSettingsAsProps( m_pImpl->m_xSettings, UNO_QUERY_THROW );
+ Reference< XPropertySetInfo > xPST( xSettingsAsProps->getPropertySetInfo(), UNO_QUERY_THROW );
+ Sequence< Property > aSettings( xPST->getProperties() );
+ ::std::map< ::rtl::OUString, sal_Int32 > aPropertyAttributes;
+ for ( const Property* pSettings = aSettings.getConstArray();
+ pSettings != aSettings.getConstArray() + aSettings.getLength();
+ ++pSettings
+ )
+ {
+ aPropertyAttributes[ pSettings->Name ] = pSettings->Attributes;
+ }
+
+ // get all current settings with their values
+ Sequence< PropertyValue > aValues( m_pImpl->m_xSettings->getPropertyValues() );
+
+ // transform them so that only property values which fulfill certain
+ // criterions survive
+ Sequence< PropertyValue > aNonDefaultOrUserDefined( aValues.getLength() );
+ const PropertyValue* pCopyEnd = ::std::remove_copy_if(
+ aValues.getConstArray(),
+ aValues.getConstArray() + aValues.getLength(),
+ aNonDefaultOrUserDefined.getArray(),
+ IsDefaultAndNotRemoveable( aPropertyAttributes )
+ );
+ aNonDefaultOrUserDefined.realloc( pCopyEnd - aNonDefaultOrUserDefined.getArray() );
+ rValue <<= aNonDefaultOrUserDefined;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+ break;
+ case PROPERTY_ID_SETTINGS:
+ rValue <<= m_pImpl->m_xSettings;
+ break;
+ case PROPERTY_ID_URL:
+ rValue <<= m_pImpl->m_sConnectURL;
+ break;
+ case PROPERTY_ID_NUMBERFORMATSSUPPLIER:
+ rValue <<= m_pImpl->getNumberFormatsSupplier();
+ break;
+ case PROPERTY_ID_NAME:
+ rValue <<= m_pImpl->m_sName;
+ break;
+ case PROPERTY_ID_LAYOUTINFORMATION:
+ rValue <<= m_pImpl->m_aLayoutInformation;
+ break;
+ default:
+ DBG_ERROR("unknown Property");
+ }
+ }
+}
+
+// XDataSource
+void ODatabaseSource::setLoginTimeout(sal_Int32 seconds) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::setLoginTimeout" );
+ ModelMethodGuard aGuard( *this );
+ m_pImpl->m_nLoginTimeout = seconds;
+}
+
+sal_Int32 ODatabaseSource::getLoginTimeout(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::getLoginTimeout" );
+ ModelMethodGuard aGuard( *this );
+ return m_pImpl->m_nLoginTimeout;
+}
+
+// XCompletedConnection
+Reference< XConnection > SAL_CALL ODatabaseSource::connectWithCompletion( const Reference< XInteractionHandler >& _rxHandler ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::connectWithCompletion" );
+ return connectWithCompletion(_rxHandler,sal_False);
+}
+
+Reference< XConnection > ODatabaseSource::getConnection(const rtl::OUString& user, const rtl::OUString& password) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::getConnection" );
+ return getConnection(user,password,sal_False);
+}
+
+Reference< XConnection > SAL_CALL ODatabaseSource::getIsolatedConnection( const ::rtl::OUString& user, const ::rtl::OUString& password ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::getIsolatedConnection" );
+ return getConnection(user,password,sal_True);
+}
+
+Reference< XConnection > SAL_CALL ODatabaseSource::getIsolatedConnectionWithCompletion( const Reference< XInteractionHandler >& _rxHandler ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::getIsolatedConnectionWithCompletion" );
+ return connectWithCompletion(_rxHandler,sal_True);
+}
+
+Reference< XConnection > SAL_CALL ODatabaseSource::connectWithCompletion( const Reference< XInteractionHandler >& _rxHandler,sal_Bool _bIsolated ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::connectWithCompletion" );
+ ModelMethodGuard aGuard( *this );
+
+ if (!_rxHandler.is())
+ {
+ DBG_ERROR("ODatabaseSource::connectWithCompletion: invalid interaction handler!");
+ return getConnection(m_pImpl->m_sUser, m_pImpl->m_aPassword,_bIsolated);
+ }
+
+ ::rtl::OUString sUser(m_pImpl->m_sUser), sPassword(m_pImpl->m_aPassword);
+ sal_Bool bNewPasswordGiven = sal_False;
+
+ if (m_pImpl->m_bPasswordRequired && (0 == sPassword.getLength()))
+ { // we need a password, but don't have one yet.
+ // -> ask the user
+
+ // build an interaction request
+ // two continuations (Ok and Cancel)
+ OInteractionAbort* pAbort = new OInteractionAbort;
+ OAuthenticationContinuation* pAuthenticate = new OAuthenticationContinuation;
+
+ // the name which should be referred in the login dialog
+ ::rtl::OUString sServerName( m_pImpl->m_sName );
+ INetURLObject aURLCheck( sServerName );
+ if ( aURLCheck.GetProtocol() != INET_PROT_NOT_VALID )
+ sServerName = aURLCheck.getBase( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_UNAMBIGUOUS );
+
+ // the request
+ AuthenticationRequest aRequest;
+ aRequest.ServerName = sServerName;
+ aRequest.HasRealm = aRequest.HasAccount = sal_False;
+ aRequest.HasUserName = aRequest.HasPassword = sal_True;
+ aRequest.UserName = m_pImpl->m_sUser;
+ aRequest.Password = m_pImpl->m_sFailedPassword.getLength() ? m_pImpl->m_sFailedPassword : m_pImpl->m_aPassword;
+ OInteractionRequest* pRequest = new OInteractionRequest(makeAny(aRequest));
+ Reference< XInteractionRequest > xRequest(pRequest);
+ // some knittings
+ pRequest->addContinuation(pAbort);
+ pRequest->addContinuation(pAuthenticate);
+
+ // handle the request
+ try
+ {
+ MutexRelease aRelease( getMutex() );
+ // release the mutex when calling the handler, it may need to lock the SolarMutex
+ _rxHandler->handle(xRequest);
+ }
+ catch(Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ if (!pAuthenticate->wasSelected())
+ return Reference< XConnection >();
+
+ // get the result
+ sUser = m_pImpl->m_sUser = pAuthenticate->getUser();
+ sPassword = pAuthenticate->getPassword();
+
+ if (pAuthenticate->getRememberPassword())
+ {
+ m_pImpl->m_aPassword = pAuthenticate->getPassword();
+ bNewPasswordGiven = sal_True;
+ }
+ m_pImpl->m_sFailedPassword = ::rtl::OUString();
+ }
+
+ try
+ {
+ return getConnection(sUser, sPassword,_bIsolated);
+ }
+ catch(Exception&)
+ {
+ if (bNewPasswordGiven)
+ {
+ m_pImpl->m_sFailedPassword = m_pImpl->m_aPassword;
+ // assume that we had an authentication problem. Without this we may, after an unsucessful connect, while
+ // the user gave us a password an the order to remember it, never allow an password input again (at least
+ // not without restarting the session)
+ m_pImpl->m_aPassword = ::rtl::OUString();
+ }
+ throw;
+ }
+}
+
+Reference< XConnection > ODatabaseSource::buildIsolatedConnection(const rtl::OUString& user, const rtl::OUString& password)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::buildIsolatedConnection" );
+ Reference< XConnection > xConn;
+ Reference< XConnection > xSdbcConn = buildLowLevelConnection(user, password);
+ DBG_ASSERT( xSdbcConn.is(), "ODatabaseSource::buildIsolatedConnection: invalid return value of buildLowLevelConnection!" );
+ // buildLowLevelConnection is expected to always succeed
+ if ( xSdbcConn.is() )
+ {
+ // build a connection server and return it (no stubs)
+ xConn = new OConnection(*this, xSdbcConn, m_pImpl->m_aContext.getLegacyServiceFactory());
+ }
+ return xConn;
+}
+
+Reference< XConnection > ODatabaseSource::getConnection(const rtl::OUString& user, const rtl::OUString& password,sal_Bool _bIsolated) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::getConnection" );
+ ModelMethodGuard aGuard( *this );
+
+ Reference< XConnection > xConn;
+ if ( _bIsolated )
+ {
+ xConn = buildIsolatedConnection(user,password);
+ }
+ else
+ { // create a new proxy for the connection
+ if ( !m_pImpl->m_xSharedConnectionManager.is() )
+ {
+ m_pImpl->m_pSharedConnectionManager = new OSharedConnectionManager( m_pImpl->m_aContext.getLegacyServiceFactory() );
+ m_pImpl->m_xSharedConnectionManager = m_pImpl->m_pSharedConnectionManager;
+ }
+ xConn = m_pImpl->m_pSharedConnectionManager->getConnection(
+ m_pImpl->m_sConnectURL, user, password, m_pImpl->m_xSettings->getPropertyValues(), this );
+ }
+
+ if ( xConn.is() )
+ {
+ Reference< XComponent> xComp(xConn,UNO_QUERY);
+ if ( xComp.is() )
+ xComp->addEventListener( static_cast< XContainerListener* >( this ) );
+ m_pImpl->m_aConnections.push_back(OWeakConnection(xConn));
+ }
+
+ return xConn;
+}
+
+Reference< XNameAccess > SAL_CALL ODatabaseSource::getBookmarks( ) throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::getBookmarks" );
+ ModelMethodGuard aGuard( *this );
+ return static_cast< XNameContainer* >(&m_aBookmarks);
+}
+
+Reference< XNameAccess > SAL_CALL ODatabaseSource::getQueryDefinitions( ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::getQueryDefinitions" );
+ ModelMethodGuard aGuard( *this );
+
+ Reference< XNameAccess > xContainer = m_pImpl->m_xCommandDefinitions;
+ if ( !xContainer.is() )
+ {
+ Any aValue;
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xMy(*this);
+ if ( dbtools::getDataSourceSetting(xMy,"CommandDefinitions",aValue) )
+ {
+ ::rtl::OUString sSupportService;
+ aValue >>= sSupportService;
+ if ( sSupportService.getLength() )
+ {
+ Sequence<Any> aArgs(1);
+ aArgs[0] <<= NamedValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DataSource")),makeAny(xMy));
+ xContainer.set(m_pImpl->m_aContext.createComponentWithArguments(sSupportService,aArgs),UNO_QUERY);
+ }
+ }
+ if ( !xContainer.is() )
+ {
+ TContentPtr& rContainerData( m_pImpl->getObjectContainer( ODatabaseModelImpl::E_QUERY ) );
+ xContainer = new OCommandContainer( m_pImpl->m_aContext.getLegacyServiceFactory(), *this, rContainerData, sal_False );
+ }
+ m_pImpl->m_xCommandDefinitions = xContainer;
+ }
+ return xContainer;
+}
+
+// XTablesSupplier
+Reference< XNameAccess > ODatabaseSource::getTables() throw( RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::getTables" );
+ ModelMethodGuard aGuard( *this );
+
+ Reference< XNameAccess > xContainer = m_pImpl->m_xTableDefinitions;
+ if ( !xContainer.is() )
+ {
+ TContentPtr& rContainerData( m_pImpl->getObjectContainer( ODatabaseModelImpl::E_TABLE ) );
+ xContainer = new OCommandContainer( m_pImpl->m_aContext.getLegacyServiceFactory(), *this, rContainerData, sal_True );
+ m_pImpl->m_xTableDefinitions = xContainer;
+ }
+ return xContainer;
+}
+
+void SAL_CALL ODatabaseSource::flush( ) throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::flush" );
+ try
+ {
+ // SYNCHRONIZED ->
+ {
+ ModelMethodGuard aGuard( *this );
+
+ typedef ::utl::SharedUNOComponent< XModel, ::utl::CloseableComponent > SharedModel;
+ SharedModel xModel( m_pImpl->getModel_noCreate(), SharedModel::NoTakeOwnership );
+
+ if ( !xModel.is() )
+ xModel.reset( m_pImpl->createNewModel_deliverOwnership( false ), SharedModel::TakeOwnership );
+
+ Reference< css::frame::XStorable> xStorable( xModel, UNO_QUERY_THROW );
+ xStorable->store();
+ }
+ // <- SYNCHRONIZED
+
+ css::lang::EventObject aFlushedEvent(*this);
+ m_aFlushListeners.notifyEach( &XFlushListener::flushed, aFlushedEvent );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+}
+
+void SAL_CALL ODatabaseSource::flushed( const EventObject& /*rEvent*/ ) throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::flushed" );
+ ModelMethodGuard aGuard( *this );
+
+ // Okay, this is some hack.
+ //
+ // In general, we have the problem that embedded databases write into their underlying storage, which
+ // logically is one of our sub storage, and practically is a temporary file maintained by the
+ // package implementation. As long as we did not commit this storage and our main storage,
+ // the changes made by the embedded database engine are not really reflected in the database document
+ // file. This is Bad (TM) for a "real" database application - imagine somebody entering some
+ // data, and then crashing: For a database application, you would expect that the data still is present
+ // when you connect to the database next time.
+ //
+ // Since this is a conceptual problem as long as we do use those ZIP packages (in fact, we *cannot*
+ // provide the desired functionality as long as we do not have a package format which allows O(1) writes),
+ // we cannot completely fix this. However, we can relax the problem by commiting more often - often
+ // enough so that data loss is more seldom, and seldom enough so that there's no noticable performance
+ // decrease.
+ //
+ // For this, we introduced a few places which XFlushable::flush their connections, and register as
+ // XFlushListener at the embedded connection (which needs to provide the XFlushable functionality).
+ // Then, when the connection is flushed, we commit both the database storage and our main storage.
+ //
+ // #i55274# / 2005-09-30 / frank.schoenheit@sun.com
+
+ OSL_ENSURE( m_pImpl->isEmbeddedDatabase(), "ODatabaseSource::flushed: no embedded database?!" );
+ sal_Bool bWasModified = m_pImpl->m_bModified;
+ m_pImpl->commitEmbeddedStorage();
+ m_pImpl->setModified( bWasModified );
+}
+
+void SAL_CALL ODatabaseSource::addFlushListener( const Reference< ::com::sun::star::util::XFlushListener >& _xListener ) throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::addFlushListener" );
+ m_aFlushListeners.addInterface(_xListener);
+}
+
+void SAL_CALL ODatabaseSource::removeFlushListener( const Reference< ::com::sun::star::util::XFlushListener >& _xListener ) throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::removeFlushListener" );
+ m_aFlushListeners.removeInterface(_xListener);
+}
+
+void SAL_CALL ODatabaseSource::elementInserted( const ContainerEvent& /*Event*/ ) throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::elementInserted" );
+ ModelMethodGuard aGuard( *this );
+ if ( m_pImpl.is() )
+ m_pImpl->setModified(sal_True);
+}
+
+void SAL_CALL ODatabaseSource::elementRemoved( const ContainerEvent& /*Event*/ ) throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::elementRemoved" );
+ ModelMethodGuard aGuard( *this );
+ if ( m_pImpl.is() )
+ m_pImpl->setModified(sal_True);
+}
+
+void SAL_CALL ODatabaseSource::elementReplaced( const ContainerEvent& /*Event*/ ) throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::elementReplaced" );
+ ModelMethodGuard aGuard( *this );
+ if ( m_pImpl.is() )
+ m_pImpl->setModified(sal_True);
+}
+
+// XDocumentDataSource
+Reference< XOfficeDatabaseDocument > SAL_CALL ODatabaseSource::getDatabaseDocument() throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::getDatabaseDocument" );
+ ModelMethodGuard aGuard( *this );
+
+ Reference< XModel > xModel( m_pImpl->getModel_noCreate() );
+ if ( !xModel.is() )
+ xModel = m_pImpl->createNewModel_deliverOwnership( false );
+
+ return Reference< XOfficeDatabaseDocument >( xModel, UNO_QUERY_THROW );
+}
+
+Reference< XInterface > ODatabaseSource::getThis() const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "ODatabaseSource::getThis" );
+ return *const_cast< ODatabaseSource* >( this );
+}
+
+} // namespace dbaccess
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/datasource.hxx b/dbaccess/source/core/dataaccess/datasource.hxx
new file mode 100644
index 000000000000..6bc9175101f6
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/datasource.hxx
@@ -0,0 +1,239 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _DBA_COREDATAACCESS_DATASOURCE_HXX_
+#define _DBA_COREDATAACCESS_DATASOURCE_HXX_
+
+#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/sdbc/XDataSource.hpp>
+#include <com/sun/star/container/XContainerListener.hpp>
+#include <com/sun/star/sdb/XBookmarksSupplier.hpp>
+#include <com/sun/star/sdb/XQueryDefinitionsSupplier.hpp>
+#include <com/sun/star/sdbc/XIsolatedConnection.hpp>
+#include <com/sun/star/util/XNumberFormatter.hpp>
+#include <com/sun/star/document/XEventListener.hpp>
+#include <com/sun/star/util/XFlushable.hpp>
+#include <cppuhelper/propshlp.hxx>
+#include <comphelper/proparrhlp.hxx>
+#include <cppuhelper/weakref.hxx>
+#include <cppuhelper/compbase11.hxx>
+#include <com/sun/star/embed/XTransactionListener.hpp>
+#include "apitools.hxx"
+#include "bookmarkcontainer.hxx"
+#include <rtl/ref.hxx>
+#include <tools/string.hxx>
+#include <connectivity/CommonTools.hxx>
+#include <comphelper/broadcasthelper.hxx>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/sdb/XCompletedConnection.hpp>
+#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
+#include <com/sun/star/embed/XStorage.hpp>
+#include "ContentHelper.hxx"
+#include <com/sun/star/document/XStorageBasedDocument.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/util/XRefreshable.hpp>
+#include <com/sun/star/sdb/XDocumentDataSource.hpp>
+#include "ModelImpl.hxx"
+
+namespace dbaccess
+{
+
+class OSharedConnectionManager;
+class OChildCommitListen_Impl;
+
+//============================================================
+//= ODatabaseSource
+//============================================================
+typedef ::cppu::WeakComponentImplHelper11 < ::com::sun::star::lang::XServiceInfo
+ , ::com::sun::star::sdbc::XDataSource
+ , ::com::sun::star::sdb::XBookmarksSupplier
+ , ::com::sun::star::sdb::XQueryDefinitionsSupplier
+ , ::com::sun::star::sdb::XCompletedConnection
+ , ::com::sun::star::container::XContainerListener
+ , ::com::sun::star::sdbc::XIsolatedConnection
+ , ::com::sun::star::sdbcx::XTablesSupplier
+ , ::com::sun::star::util::XFlushable
+ , ::com::sun::star::util::XFlushListener
+ , ::com::sun::star::sdb::XDocumentDataSource
+ > ODatabaseSource_Base;
+
+
+class ODatabaseSource :public ModelDependentComponent // must be first
+ ,public ODatabaseSource_Base
+ ,public ::cppu::OPropertySetHelper
+ ,public ::comphelper::OPropertyArrayUsageHelper < ODatabaseSource >
+{
+ friend class ODatabaseContext;
+ friend class OConnection;
+ friend class OSharedConnectionManager;
+
+private:
+ using ODatabaseSource_Base::rBHelper;
+ OBookmarkContainer m_aBookmarks;
+ ::cppu::OInterfaceContainerHelper m_aFlushListeners;
+
+private:
+ virtual ~ODatabaseSource();
+
+public:
+ ODatabaseSource( const ::rtl::Reference< ODatabaseModelImpl >& _pImpl );
+
+ struct DBContextAccess { friend class ODatabaseContext; private: DBContextAccess() { } };
+
+ /** sets a new name for the data source
+
+ The name of a data source (our m_sName member) is the registration name, *if* the
+ data source actually *is* registered at the database context.
+
+ Normally, this name is passed at time of creation of the ODatabaseModelImpl instance,
+ but if a newly creaed data source is registered, then it must be possible to propagate
+ the new trgistration name.
+ */
+ static void setName(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XDocumentDataSource >& _rxDocument,
+ const ::rtl::OUString& _rNewName,
+ DBContextAccess
+ );
+
+ // XContainerListener
+ virtual void SAL_CALL elementInserted( const ::com::sun::star::container::ContainerEvent& Event ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL elementRemoved( const ::com::sun::star::container::ContainerEvent& Event ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL elementReplaced( const ::com::sun::star::container::ContainerEvent& Event ) throw (::com::sun::star::uno::RuntimeException);
+ // ::com::sun::star::sdbcx::XTablesSupplier
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL getTables( ) throw(::com::sun::star::uno::RuntimeException);
+
+// com::sun::star::lang::XTypeProvider
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException);
+
+// com::sun::star::uno::XInterface
+ virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL acquire() throw( );
+ virtual void SAL_CALL release() throw( );
+
+// ::com::sun::star::lang::XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException);
+
+// ::com::sun::star::lang::XServiceInfo - static methods
+ static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_static(void) throw( ::com::sun::star::uno::RuntimeException );
+ static ::rtl::OUString getImplementationName_static(void) throw( ::com::sun::star::uno::RuntimeException );
+ static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >
+ SAL_CALL Create(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >&);
+
+// OComponentHelper
+ virtual void SAL_CALL disposing(void);
+
+// com::sun::star::beans::XPropertySet
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) throw(::com::sun::star::uno::RuntimeException);
+ // XEventListener
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException);
+
+// comphelper::OPropertyArrayUsageHelper
+ virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;
+
+// cppu::OPropertySetHelper
+ virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
+
+ virtual sal_Bool SAL_CALL convertFastPropertyValue(
+ ::com::sun::star::uno::Any & rConvertedValue,
+ ::com::sun::star::uno::Any & rOldValue,
+ sal_Int32 nHandle,
+ const ::com::sun::star::uno::Any& rValue )
+ throw (::com::sun::star::lang::IllegalArgumentException);
+ virtual void SAL_CALL setFastPropertyValue_NoBroadcast(
+ sal_Int32 nHandle,
+ const ::com::sun::star::uno::Any& rValue
+ )
+ throw (::com::sun::star::uno::Exception);
+ virtual void SAL_CALL getFastPropertyValue( ::com::sun::star::uno::Any& rValue, sal_Int32 nHandle ) const;
+
+// ::com::sun::star::sdb::XCompletedConnection
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > SAL_CALL connectWithCompletion( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& handler ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+
+// ::com::sun::star::sdbc::XDataSource
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > SAL_CALL getConnection( const ::rtl::OUString& user, const ::rtl::OUString& password ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setLoginTimeout( sal_Int32 seconds ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getLoginTimeout( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+
+// :: com::sun::star::sdb::XBookmarksSupplier
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL getBookmarks( ) throw (::com::sun::star::uno::RuntimeException);
+
+// :: com::sun::star::sdb::XQueryDefinitionsSupplier
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL getQueryDefinitions( ) throw(::com::sun::star::uno::RuntimeException);
+
+// ::com::sun::star::sdbc::XIsolatedConnection
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > SAL_CALL getIsolatedConnection( const ::rtl::OUString& user, const ::rtl::OUString& password ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > SAL_CALL getIsolatedConnectionWithCompletion( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& handler ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+
+// XFlushable
+ virtual void SAL_CALL flush( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addFlushListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XFlushListener >& l ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeFlushListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XFlushListener >& l ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XFlushListener
+ virtual void SAL_CALL flushed( const ::com::sun::star::lang::EventObject& rEvent ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XDocumentDataSource
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XOfficeDatabaseDocument > SAL_CALL getDatabaseDocument() throw (::com::sun::star::uno::RuntimeException);
+
+protected:
+ // ModelDependentComponent overridables
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > getThis() const;
+
+private:
+// helper
+ /** open a connection for the current settings. this is the simple connection we get from the driver
+ manager, so it can be used as a master for a "high level" sdb connection.
+ */
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > buildLowLevelConnection(
+ const ::rtl::OUString& _rUid, const ::rtl::OUString& _rPwd
+ );
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > buildIsolatedConnection(
+ const rtl::OUString& user, const rtl::OUString& password
+ );
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > SAL_CALL getConnection( const ::rtl::OUString& user, const ::rtl::OUString& password , sal_Bool _bIsolated) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > SAL_CALL connectWithCompletion( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& handler , sal_Bool _bIsolated) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+
+ void clearConnections();
+
+protected:
+ using ::cppu::OPropertySetHelper::getFastPropertyValue;
+};
+
+} // namespace dbaccess
+
+#endif // _DBA_COREDATAACCESS_DATALINK_HXX_
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/definitioncontainer.cxx b/dbaccess/source/core/dataaccess/definitioncontainer.cxx
new file mode 100644
index 000000000000..0efce9c4aa11
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/definitioncontainer.cxx
@@ -0,0 +1,681 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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"
+
+#include "definitioncontainer.hxx"
+#include "dbastrings.hrc"
+#include "apitools.hxx"
+#include "core_resource.hxx"
+#include "core_resource.hrc"
+
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+#include <comphelper/sequence.hxx>
+#include <comphelper/enumhelper.hxx>
+#include <comphelper/extract.hxx>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/ucb/CommandInfo.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/sdb/ErrorCondition.hpp>
+#include <comphelper/types.hxx>
+#include <ucbhelper/contentidentifier.hxx>
+
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::sdb;
+using namespace ::osl;
+using namespace ::comphelper;
+using namespace ::cppu;
+using namespace ::com::sun::star::ucb;
+
+namespace dbaccess
+{
+
+//==========================================================================
+//= ODefinitionContainer_Impl
+//==========================================================================
+void ODefinitionContainer_Impl::erase( TContentPtr _pDefinition )
+{
+ NamedDefinitions::iterator aPos = find( _pDefinition );
+ if ( aPos != end() )
+ m_aDefinitions.erase( aPos );
+}
+
+ODefinitionContainer_Impl::const_iterator ODefinitionContainer_Impl::find( TContentPtr _pDefinition ) const
+{
+ return ::std::find_if(
+ m_aDefinitions.begin(),
+ m_aDefinitions.end(),
+ ::std::compose1(
+ ::std::bind2nd( ::std::equal_to< TContentPtr >(), _pDefinition ),
+ ::std::select2nd< NamedDefinitions::value_type >()
+ )
+ );
+}
+
+ODefinitionContainer_Impl::iterator ODefinitionContainer_Impl::find( TContentPtr _pDefinition )
+{
+ return ::std::find_if(
+ m_aDefinitions.begin(),
+ m_aDefinitions.end(),
+ ::std::compose1(
+ ::std::bind2nd( ::std::equal_to< TContentPtr >(), _pDefinition ),
+ ::std::select2nd< NamedDefinitions::value_type >()
+ )
+ );
+}
+
+//==========================================================================
+//= ODefinitionContainer
+//==========================================================================
+DBG_NAME(ODefinitionContainer)
+
+ODefinitionContainer::ODefinitionContainer( const Reference< XMultiServiceFactory >& _xORB
+ , const Reference< XInterface >& _xParentContainer
+ , const TContentPtr& _pImpl
+ , bool _bCheckSlash
+ )
+ :OContentHelper(_xORB,_xParentContainer,_pImpl)
+ ,m_aApproveListeners(m_aMutex)
+ ,m_aContainerListeners(m_aMutex)
+ ,m_bInPropertyChange(sal_False)
+ ,m_bCheckSlash(_bCheckSlash)
+{
+ m_pImpl->m_aProps.bIsDocument = sal_False;
+ m_pImpl->m_aProps.bIsFolder = sal_True;
+
+ const ODefinitionContainer_Impl& rDefinitions( getDefinitions() );
+ ODefinitionContainer_Impl::const_iterator aEnd = rDefinitions.end();
+ for ( ODefinitionContainer_Impl::const_iterator aDefinition = rDefinitions.begin();
+ aDefinition != aEnd;
+ ++aDefinition
+ )
+ m_aDocuments.push_back(
+ m_aDocumentMap.insert(
+ Documents::value_type( aDefinition->first, Documents::mapped_type() ) ).first );
+
+ DBG_CTOR(ODefinitionContainer, NULL);
+}
+
+void SAL_CALL ODefinitionContainer::disposing()
+{
+ OContentHelper::disposing();
+
+ MutexGuard aGuard(m_aMutex);
+
+ // say our listeners goobye
+ EventObject aEvt(*this);
+ m_aApproveListeners.disposeAndClear(aEvt);
+ m_aContainerListeners.disposeAndClear(aEvt);
+
+ // dispose our elements
+ Documents::iterator aIter = m_aDocumentMap.begin();
+ Documents::iterator aEnd = m_aDocumentMap.end();
+
+ for (; aIter != aEnd; ++aIter)
+ {
+ Reference<XContent> xProp = aIter->second;
+ if ( xProp.is() )
+ {
+ removeObjectListener(xProp);
+ ::comphelper::disposeComponent(xProp);
+ }
+ }
+
+ // remove our elements
+ m_aDocuments.clear();
+ // !!! do this before clearing the map which the vector elements refer to !!!
+ m_aDocumentMap.clear();
+}
+
+ODefinitionContainer::~ODefinitionContainer()
+{
+ DBG_DTOR(ODefinitionContainer, NULL);
+}
+
+IMPLEMENT_FORWARD_XINTERFACE2( ODefinitionContainer,OContentHelper,ODefinitionContainer_Base)
+IMPLEMENT_TYPEPROVIDER2(ODefinitionContainer,OContentHelper,ODefinitionContainer_Base);
+// XServiceInfo
+::rtl::OUString SAL_CALL ODefinitionContainer::getImplementationName( ) throw(RuntimeException)
+{
+ return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdb.ODefinitionContainer"));
+}
+
+Sequence< ::rtl::OUString > SAL_CALL ODefinitionContainer::getSupportedServiceNames( ) throw(RuntimeException)
+{
+ Sequence< ::rtl::OUString > aReturn(2);
+ aReturn.getArray()[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdb.DefinitionContainer"));
+ aReturn.getArray()[1] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.ucb.Content"));
+ return aReturn;
+}
+
+// XNameContainer
+void SAL_CALL ODefinitionContainer::insertByName( const ::rtl::OUString& _rName, const Any& aElement ) throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
+{
+ ResettableMutexGuard aGuard(m_aMutex);
+
+ // approve the new object
+ Reference< XContent > xNewElement(aElement,UNO_QUERY);
+ approveNewObject( _rName, xNewElement ); // will throw if necessary
+
+ notifyByName( aGuard, _rName, xNewElement, NULL, E_INSERTED, ApproveListeners );
+ implAppend( _rName, xNewElement );
+ notifyByName( aGuard, _rName, xNewElement, NULL, E_INSERTED, ContainerListemers );
+}
+
+void SAL_CALL ODefinitionContainer::removeByName( const ::rtl::OUString& _rName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ ResettableMutexGuard aGuard(m_aMutex);
+
+ // check the arguments
+ if (!_rName.getLength())
+ throw IllegalArgumentException();
+
+ if (!checkExistence(_rName))
+ throw NoSuchElementException(_rName,*this);
+
+ // the old element (for the notifications)
+ Reference< XContent > xOldElement = implGetByName( _rName, impl_haveAnyListeners_nothrow() );
+
+ // do the removal
+ notifyByName( aGuard, _rName, NULL, xOldElement, E_REMOVED, ApproveListeners );
+ implRemove( _rName );
+ notifyByName( aGuard, _rName, NULL, xOldElement, E_REMOVED, ContainerListemers );
+
+ removeObjectListener( xOldElement );
+ disposeComponent(xOldElement);
+}
+
+// XNameReplace
+void SAL_CALL ODefinitionContainer::replaceByName( const ::rtl::OUString& _rName, const Any& aElement ) throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ ResettableMutexGuard aGuard(m_aMutex);
+
+ // let derived classes approve the new object
+ Reference< XContent > xNewElement(aElement,UNO_QUERY);
+ approveNewObject( _rName, xNewElement ); // will throw if necessary
+
+ // the old element (for the notifications)
+ Reference< XContent > xOldElement = implGetByName( _rName, impl_haveAnyListeners_nothrow() );
+
+ notifyByName( aGuard, _rName, xNewElement, xOldElement, E_REPLACED, ApproveListeners );
+ implReplace( _rName, xNewElement );
+ notifyByName( aGuard, _rName, xNewElement, xOldElement, E_REPLACED, ContainerListemers );
+
+ // and dispose it
+ disposeComponent(xOldElement);
+}
+
+namespace
+{
+ typedef Reference< XVeto > ( SAL_CALL XContainerApproveListener::*ContainerApprovalMethod )( const ContainerEvent& );
+
+ struct RaiseExceptionFromVeto
+ {
+ private:
+ ContainerApprovalMethod m_pMethod;
+ const ContainerEvent& m_rEvent;
+
+ public:
+ RaiseExceptionFromVeto( ContainerApprovalMethod _pMethod, const ContainerEvent& _rEvent )
+ :m_pMethod( _pMethod )
+ ,m_rEvent( _rEvent )
+ {
+ }
+
+ void operator()( const Reference< XContainerApproveListener >& _Listener ) const
+ {
+ Reference< XVeto > xVeto = (_Listener.get()->*m_pMethod)( m_rEvent );
+ if ( !xVeto.is() )
+ return;
+
+ Any eVetoDetails = xVeto->getDetails();
+
+ IllegalArgumentException aIllegalArgumentError;
+ if ( eVetoDetails >>= aIllegalArgumentError )
+ throw aIllegalArgumentError;
+
+ WrappedTargetException aWrappedError;
+ if ( eVetoDetails >>= aWrappedError )
+ throw aWrappedError;
+
+ throw WrappedTargetException( xVeto->getReason(), _Listener.get(), eVetoDetails );
+ }
+ };
+}
+
+void ODefinitionContainer::notifyByName( ResettableMutexGuard& _rGuard, const ::rtl::OUString& _rName,
+ const Reference< XContent >& _xNewElement, const Reference< XContent >& _xOldElement,
+ ContainerOperation _eOperation, ListenerType _eType )
+{
+ bool bApprove = ( _eType == ApproveListeners );
+
+ ::cppu::OInterfaceContainerHelper& rContainer( bApprove ? m_aApproveListeners : m_aContainerListeners );
+ if ( !rContainer.getLength() )
+ return;
+
+ ContainerEvent aEvent( *this, makeAny( _rName ), makeAny( _xNewElement ), makeAny( _xOldElement ) );
+
+ _rGuard.clear();
+ switch ( _eOperation )
+ {
+ case E_INSERTED:
+ if ( bApprove )
+ rContainer.forEach< XContainerApproveListener, RaiseExceptionFromVeto >(
+ RaiseExceptionFromVeto( &XContainerApproveListener::approveInsertElement, aEvent ) );
+ else
+ rContainer.notifyEach( &XContainerListener::elementInserted, aEvent );
+ break;
+ case E_REPLACED:
+ if ( bApprove )
+ rContainer.forEach< XContainerApproveListener, RaiseExceptionFromVeto >(
+ RaiseExceptionFromVeto( &XContainerApproveListener::approveReplaceElement, aEvent ) );
+ else
+ rContainer.notifyEach( &XContainerListener::elementReplaced, aEvent );
+ break;
+ case E_REMOVED:
+ if ( bApprove )
+ rContainer.forEach< XContainerApproveListener, RaiseExceptionFromVeto >(
+ RaiseExceptionFromVeto( &XContainerApproveListener::approveRemoveElement, aEvent ) );
+ else
+ rContainer.notifyEach( &XContainerListener::elementRemoved, aEvent );
+ break;
+ }
+
+ if ( bApprove )
+ _rGuard.reset();
+}
+
+void SAL_CALL ODefinitionContainer::addContainerListener( const Reference< XContainerListener >& _rxListener ) throw(RuntimeException)
+{
+ if (_rxListener.is())
+ m_aContainerListeners.addInterface(_rxListener);
+}
+
+void SAL_CALL ODefinitionContainer::removeContainerListener( const Reference< XContainerListener >& _rxListener ) throw(RuntimeException)
+{
+ if (_rxListener.is())
+ m_aContainerListeners.removeInterface(_rxListener);
+}
+
+void SAL_CALL ODefinitionContainer::addContainerApproveListener( const Reference< XContainerApproveListener >& _Listener ) throw (RuntimeException)
+{
+ if ( _Listener.is() )
+ m_aApproveListeners.addInterface( _Listener );
+}
+
+void SAL_CALL ODefinitionContainer::removeContainerApproveListener( const Reference< XContainerApproveListener >& _Listener ) throw (RuntimeException)
+{
+ if ( _Listener.is() )
+ m_aApproveListeners.removeInterface( _Listener );
+}
+
+// XElementAccess
+Type SAL_CALL ODefinitionContainer::getElementType( ) throw (RuntimeException)
+{
+ return ::getCppuType( static_cast< Reference< XContent >* >(NULL) );
+}
+
+sal_Bool SAL_CALL ODefinitionContainer::hasElements( ) throw (RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ return !m_aDocuments.empty();
+}
+
+// XEnumerationAccess
+Reference< XEnumeration > SAL_CALL ODefinitionContainer::createEnumeration( ) throw(RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ return new ::comphelper::OEnumerationByIndex(static_cast<XIndexAccess*>(this));
+}
+
+// XIndexAccess
+sal_Int32 SAL_CALL ODefinitionContainer::getCount( ) throw(RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ return m_aDocuments.size();
+}
+
+Any SAL_CALL ODefinitionContainer::getByIndex( sal_Int32 _nIndex ) throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+
+ if ((_nIndex < 0) || (_nIndex >= (sal_Int32)m_aDocuments.size()))
+ throw IndexOutOfBoundsException();
+
+ Documents::iterator aPos = m_aDocuments[_nIndex];
+ Reference<XContent> xProp = aPos->second;
+ if (!xProp.is())
+ { // that's the first access to the object
+ // -> create it
+ xProp = createObject(aPos->first);
+ aPos->second = Documents::mapped_type();
+ // and update the name-access map
+ }
+
+ return makeAny(xProp);
+}
+
+Any SAL_CALL ODefinitionContainer::getByName( const ::rtl::OUString& _rName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+
+ return makeAny( implGetByName( _rName, sal_True ) );
+}
+
+Reference< XContent > ODefinitionContainer::implGetByName(const ::rtl::OUString& _rName, sal_Bool _bReadIfNeccessary) throw (NoSuchElementException)
+{
+ Documents::iterator aMapPos = m_aDocumentMap.find(_rName);
+ if (aMapPos == m_aDocumentMap.end())
+ throw NoSuchElementException(_rName,*this);
+
+ Reference< XContent > xProp = aMapPos->second;
+
+ if (_bReadIfNeccessary && !xProp.is())
+ { // the object has never been accessed before, so we have to read it now
+ // (that's the expensive part)
+
+ // create the object and insert it into the map
+ xProp = createObject(_rName);
+ aMapPos->second = xProp;
+ addObjectListener(xProp);
+ }
+
+ return xProp;
+}
+
+Sequence< ::rtl::OUString > SAL_CALL ODefinitionContainer::getElementNames( ) throw(RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+
+ Sequence< ::rtl::OUString > aNames(m_aDocumentMap.size());
+ ::rtl::OUString* pNames = aNames.getArray();
+ Documents::iterator aEnd = m_aDocumentMap.end();
+ for ( Documents::iterator aNameIter = m_aDocumentMap.begin();
+ aNameIter != aEnd;
+ ++pNames, ++aNameIter
+ )
+ {
+ *pNames = aNameIter->first;
+ }
+
+ return aNames;
+}
+
+sal_Bool SAL_CALL ODefinitionContainer::hasByName( const ::rtl::OUString& _rName ) throw(RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+
+ return checkExistence(_rName);
+}
+
+void SAL_CALL ODefinitionContainer::disposing( const EventObject& _rSource ) throw(RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ Reference< XContent > xSource(_rSource.Source, UNO_QUERY);
+ // it's one of our documents ....
+ Documents::iterator aIter = m_aDocumentMap.begin();
+ Documents::iterator aEnd = m_aDocumentMap.end();
+ for (;aIter != aEnd;++aIter )
+ {
+ if ( xSource == aIter->second.get() )
+ {
+ removeObjectListener(xSource);
+ // and clear our document map/vector, so the object will be recreated on next access
+ aIter->second = Documents::mapped_type();
+ }
+ }
+}
+
+void ODefinitionContainer::implRemove(const ::rtl::OUString& _rName)
+{
+ // from the object maps
+ Documents::iterator aFind = m_aDocumentMap.find(_rName);
+ if ( aFind != m_aDocumentMap.end() )
+ {
+ m_aDocuments.erase( ::std::find(m_aDocuments.begin(),m_aDocuments.end(),aFind));
+ m_aDocumentMap.erase(aFind);
+
+ getDefinitions().erase( _rName );
+
+ notifyDataSourceModified();
+ }
+}
+
+namespace
+{
+ bool lcl_ensureName( const Reference< XContent >& _rxContent, const ::rtl::OUString& _rName )
+ {
+ if ( !_rxContent.is() )
+ return true;
+
+ // obtain the current name. If it's the same as the new one,
+ // don't do anything
+ try
+ {
+ Reference< XPropertySet > xProps( _rxContent, UNO_QUERY );
+ if ( xProps.is() )
+ {
+ ::rtl::OUString sCurrentName;
+ OSL_VERIFY( xProps->getPropertyValue( PROPERTY_NAME ) >>= sCurrentName );
+ if ( sCurrentName.equals( _rName ) )
+ return true;
+ }
+ }
+ catch( const Exception& )
+ {
+ OSL_ENSURE( sal_False, "lcl_ensureName: caught an exception while obtaining the current name!" );
+ }
+
+ // set the new name
+ Reference< XRename > xRename( _rxContent, UNO_QUERY );
+ OSL_ENSURE( xRename.is(), "lcl_ensureName: invalid content (not renameable)!" );
+ if ( !xRename.is() )
+ return false;
+ try
+ {
+ xRename->rename( _rName );
+ return true;
+ }
+ catch( const Exception& )
+ {
+ OSL_ENSURE( sal_False, "lcl_ensureName: caught an exception!" );
+ }
+ return false;
+ }
+}
+
+void ODefinitionContainer::implAppend(const ::rtl::OUString& _rName, const Reference< XContent >& _rxNewObject)
+{
+ MutexGuard aGuard(m_aMutex);
+ try
+ {
+ Reference<XChild> xChild(_rxNewObject,UNO_QUERY);
+ if ( xChild.is() )
+ xChild->setParent(static_cast<OWeakObject*>(this));
+
+ ODefinitionContainer_Impl& rDefinitions( getDefinitions() );
+ ODefinitionContainer_Impl::const_iterator aFind = rDefinitions.find( _rName );
+ if ( aFind == rDefinitions.end() )
+ {
+ // ensure that the new object thas the proper name.
+ // Somebody could create an object with name "foo", and insert it as "bar"
+ // into a container. In this case, we need to ensure that the object name
+ // is also "bar"
+ // #i44786# / 2005-03-11 / frank.schoenheit@sun.com
+ lcl_ensureName( _rxNewObject, _rName );
+
+ ::rtl::Reference< OContentHelper > pContent = OContentHelper::getImplementation( _rxNewObject );
+ if ( pContent.is() )
+ {
+ TContentPtr pImpl = pContent->getImpl();
+ rDefinitions.erase( pImpl );
+ pImpl->m_aProps.aTitle = _rName;
+ rDefinitions.insert( _rName, pImpl );
+ }
+ }
+
+
+ m_aDocuments.push_back(m_aDocumentMap.insert(Documents::value_type(_rName,_rxNewObject)).first);
+ notifyDataSourceModified();
+ // now update our structures
+ if ( _rxNewObject.is() )
+ addObjectListener(_rxNewObject);
+ }
+ catch(Exception&)
+ {
+ DBG_ERROR("ODefinitionContainer::implAppend: caught something !");
+ }
+}
+
+void ODefinitionContainer::implReplace(const ::rtl::OUString& _rName, const Reference< XContent >& _rxNewObject)
+{
+ DBG_ASSERT(checkExistence(_rName), "ODefinitionContainer::implReplace : invalid name !");
+
+ Documents::iterator aFind = m_aDocumentMap.find(_rName);
+ removeObjectListener(aFind->second);
+ aFind->second = _rxNewObject;
+ addObjectListener(aFind->second);
+}
+
+void ODefinitionContainer::approveNewObject(const ::rtl::OUString& _sName,const Reference< XContent >& _rxObject) const
+{
+ // check the arguments
+ if ( !_sName.getLength() )
+ throw IllegalArgumentException(
+ DBA_RES( RID_STR_NAME_MUST_NOT_BE_EMPTY ),
+ *this,
+ 0 );
+
+ if ( m_bCheckSlash && _sName.indexOf( '/' ) != -1 )
+ throw IllegalArgumentException(
+ m_aErrorHelper.getErrorMessage( ErrorCondition::DB_OBJECT_NAME_WITH_SLASHES ),
+ *this,
+ 0 );
+
+ if ( !_rxObject.is() )
+ throw IllegalArgumentException(
+ DBA_RES( RID_STR_NO_NULL_OBJECTS_IN_CONTAINER ),
+ *this,
+ 0 );
+
+ const ODefinitionContainer_Impl& rDefinitions( getDefinitions() );
+ if ( rDefinitions.find( _sName ) != rDefinitions.end() )
+ throw ElementExistException(
+ DBA_RES( RID_STR_NAME_ALREADY_USED ),
+ *this );
+
+ ::rtl::Reference< OContentHelper > pContent( OContentHelper::getImplementation( _rxObject ) );
+ if ( !pContent.is() )
+ throw IllegalArgumentException(
+ DBA_RES( RID_STR_OBJECT_CONTAINER_MISMATCH ),
+ *this,
+ 1 );
+
+ if ( rDefinitions.find( pContent->getImpl() ) != rDefinitions.end() )
+ throw ElementExistException(
+ DBA_RES( RID_STR_OBJECT_ALREADY_CONTAINED ),
+ *this );
+}
+
+// XPropertyChangeListener
+void SAL_CALL ODefinitionContainer::propertyChange( const PropertyChangeEvent& evt ) throw (RuntimeException)
+{
+ ClearableMutexGuard aGuard(m_aMutex);
+ if(evt.PropertyName == (rtl::OUString) PROPERTY_NAME || evt.PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Title" ) ))
+ {
+ m_bInPropertyChange = sal_True;
+ try
+ {
+ ::rtl::OUString sNewName,sOldName;
+ evt.OldValue >>= sOldName;
+ evt.NewValue >>= sNewName;
+ Reference<XContent> xContent( evt.Source, UNO_QUERY );
+ removeObjectListener( xContent );
+ implRemove( sOldName );
+ implAppend( sNewName, xContent );
+ }
+ catch(const Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ throw RuntimeException();
+ }
+ m_bInPropertyChange = sal_False;
+ }
+}
+
+// XVetoableChangeListener
+void SAL_CALL ODefinitionContainer::vetoableChange( const PropertyChangeEvent& aEvent ) throw (PropertyVetoException, RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+
+ if(aEvent.PropertyName == (rtl::OUString) PROPERTY_NAME || aEvent.PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
+ {
+ ::rtl::OUString sNewName;
+ aEvent.NewValue >>= sNewName;
+ if(hasByName(sNewName))
+ throw PropertyVetoException();
+ }
+}
+
+void ODefinitionContainer::addObjectListener(const Reference< XContent >& _xNewObject)
+{
+ OSL_ENSURE(_xNewObject.is(),"ODefinitionContainer::addObjectListener: Object is null!");
+ Reference<XPropertySet> xProp(_xNewObject,UNO_QUERY);
+ if ( xProp.is() )
+ {
+ xProp->addPropertyChangeListener(PROPERTY_NAME, this);
+ xProp->addVetoableChangeListener(PROPERTY_NAME, this);
+ }
+}
+
+void ODefinitionContainer::removeObjectListener(const Reference< XContent >& _xNewObject)
+{
+ Reference<XPropertySet> xProp(_xNewObject,UNO_QUERY);
+ if ( xProp.is() )
+ {
+ xProp->removePropertyChangeListener(PROPERTY_NAME, this);
+ xProp->removeVetoableChangeListener(PROPERTY_NAME, this);
+ }
+}
+
+sal_Bool ODefinitionContainer::checkExistence(const ::rtl::OUString& _rName)
+{
+ return m_aDocumentMap.find(_rName) != m_aDocumentMap.end();
+}
+
+}
+// namespace dbaccess
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/documentcontainer.cxx b/dbaccess/source/core/dataaccess/documentcontainer.cxx
new file mode 100644
index 000000000000..8c59233ce28c
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/documentcontainer.cxx
@@ -0,0 +1,784 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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"
+
+#include "documentcontainer.hxx"
+#include "dbastrings.hrc"
+#include "documentdefinition.hxx"
+#include <com/sun/star/ucb/OpenCommandArgument2.hpp>
+#include <com/sun/star/ucb/OpenMode.hpp>
+#include <tools/debug.hxx>
+#include <connectivity/dbtools.hxx>
+#include "myucp_resultset.hxx"
+#include <ucbhelper/cancelcommandexecution.hxx>
+#include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
+#include <com/sun/star/ucb/InsertCommandArgument.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/sdb/ErrorCondition.hpp>
+#include "datasource.hxx"
+#include <comphelper/classids.hxx>
+#include <comphelper/mimeconfighelper.hxx>
+#include <comphelper/string.hxx>
+#include <connectivity/sqlerror.hxx>
+#include "core_resource.hxx"
+#include "core_resource.hrc"
+#include <comphelper/namedvaluecollection.hxx>
+
+#include <vcl/svapp.hxx>
+#include <osl/mutex.hxx>
+#include <comphelper/namedvaluecollection.hxx>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::embed;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::io;
+using namespace ::osl;
+using namespace ::comphelper;
+using namespace ::cppu;
+
+namespace dbaccess
+{
+
+//==========================================================================
+//= LocalNameApproval
+//==========================================================================
+class LocalNameApproval : public IContainerApprove
+{
+ ::connectivity::SQLError m_aErrors;
+
+public:
+ LocalNameApproval( const Reference< XMultiServiceFactory >& _rxFactory )
+ :m_aErrors( ::comphelper::ComponentContext( _rxFactory ) )
+ {
+ }
+ virtual ~LocalNameApproval()
+ {
+ }
+
+ void SAL_CALL approveElement( const ::rtl::OUString& _rName, const Reference< XInterface >& _rxElement );
+};
+
+void SAL_CALL LocalNameApproval::approveElement( const ::rtl::OUString& _rName, const Reference< XInterface >& /*_rxElement*/ )
+{
+ if ( _rName.indexOf( '/' ) != -1 )
+ throw IllegalArgumentException(
+ m_aErrors.getErrorMessage( ErrorCondition::DB_OBJECT_NAME_WITH_SLASHES ),
+ NULL,
+ 0
+ );
+}
+
+//==========================================================================
+//= ODocumentContainer
+//==========================================================================
+DBG_NAME(ODocumentContainer)
+
+ODocumentContainer::ODocumentContainer(const Reference< XMultiServiceFactory >& _xORB
+ ,const Reference< XInterface >& _xParentContainer
+ ,const TContentPtr& _pImpl
+ , sal_Bool _bFormsContainer
+ )
+ :ODefinitionContainer(_xORB,_xParentContainer,_pImpl)
+ ,OPropertyStateContainer(OContentHelper::rBHelper)
+ ,m_bFormsContainer(_bFormsContainer)
+{
+ DBG_CTOR(ODocumentContainer, NULL);
+ registerProperty(PROPERTY_NAME, PROPERTY_ID_NAME, PropertyAttribute::BOUND | PropertyAttribute::READONLY | PropertyAttribute::CONSTRAINED,
+ &m_pImpl->m_aProps.aTitle, ::getCppuType(&m_pImpl->m_aProps.aTitle));
+
+ setElementApproval( PContainerApprove( new LocalNameApproval ( _xORB ) ) );
+}
+
+ODocumentContainer::~ODocumentContainer()
+{
+ DBG_DTOR(ODocumentContainer, NULL);
+
+ if ( !OContentHelper::rBHelper.bInDispose && !OContentHelper::rBHelper.bDisposed )
+ {
+ acquire();
+ dispose();
+ }
+}
+
+IMPLEMENT_FORWARD_XINTERFACE3( ODocumentContainer,ODefinitionContainer,ODocumentContainer_Base,OPropertyStateContainer)
+IMPLEMENT_TYPEPROVIDER3(ODocumentContainer,ODefinitionContainer,OPropertyStateContainer,ODocumentContainer_Base);
+IMPLEMENT_SERVICE_INFO_IMPLNAME(ODocumentContainer, "com.sun.star.comp.dba.ODocumentContainer");
+IMPLEMENT_SERVICE_INFO_SUPPORTS(ODocumentContainer);
+IMPLEMENT_PROPERTYCONTAINER_DEFAULTS(ODocumentContainer)
+
+Sequence< ::rtl::OUString > SAL_CALL ODocumentContainer::getSupportedServiceNames( ) throw(RuntimeException)
+{
+ Sequence< ::rtl::OUString > aSupported(1);
+ aSupported[0] = m_bFormsContainer ? SERVICE_NAME_FORM_COLLECTION : SERVICE_NAME_REPORT_COLLECTION;
+ return aSupported;
+}
+
+::rtl::OUString ODocumentContainer::determineContentType() const
+{
+ return ::rtl::OUString();
+}
+
+Reference< XContent > ODocumentContainer::createObject( const ::rtl::OUString& _rName)
+{
+ const ODefinitionContainer_Impl& rDefinitions( getDefinitions() );
+ ODefinitionContainer_Impl::const_iterator aFind = rDefinitions.find( _rName );
+ OSL_ENSURE( aFind != rDefinitions.end(), "ODocumentContainer::createObject:Invalid entry in map!" );
+ if ( aFind->second->m_aProps.bIsFolder )
+ return new ODocumentContainer( m_aContext.getLegacyServiceFactory(), *this, aFind->second, m_bFormsContainer );
+ return new ODocumentDefinition( *this, m_aContext.getLegacyServiceFactory(), aFind->second, m_bFormsContainer );
+}
+
+Reference< XInterface > SAL_CALL ODocumentContainer::createInstance( const ::rtl::OUString& aServiceSpecifier ) throw (Exception, RuntimeException)
+{
+ return createInstanceWithArguments( aServiceSpecifier, Sequence< Any >() );
+}
+
+namespace
+{
+ template< class TYPE >
+ void lcl_extractAndRemove( ::comphelper::NamedValueCollection& io_rArguments, const ::rtl::OUString& i_rName, TYPE& o_rValue )
+ {
+ if ( io_rArguments.has( i_rName ) )
+ {
+ io_rArguments.get_ensureType( i_rName, o_rValue );
+ io_rArguments.remove( i_rName );
+ }
+ }
+}
+
+Reference< XInterface > SAL_CALL ODocumentContainer::createInstanceWithArguments( const ::rtl::OUString& ServiceSpecifier, const Sequence< Any >& _aArguments ) throw (Exception, RuntimeException)
+{
+ Reference< XInterface > xRet;
+ Reference< XContent > xContent;
+ if ( ServiceSpecifier == SERVICE_SDB_DOCUMENTDEFINITION )
+ {
+ MutexGuard aGuard(m_aMutex);
+
+ // extrat known arguments
+ ::rtl::OUString sName, sPersistentName, sURL, sMediaType, sDocServiceName;
+ Reference< XCommandProcessor > xCopyFrom;
+ Reference< XConnection > xConnection;
+ sal_Bool bAsTemplate( sal_False );
+ Sequence< sal_Int8 > aClassID;
+
+ ::comphelper::NamedValueCollection aArgs( _aArguments );
+ lcl_extractAndRemove( aArgs, PROPERTY_NAME, sName );
+ lcl_extractAndRemove( aArgs, PROPERTY_PERSISTENT_NAME, sPersistentName );
+ lcl_extractAndRemove( aArgs, PROPERTY_URL, sURL );
+ lcl_extractAndRemove( aArgs, PROPERTY_EMBEDDEDOBJECT, xCopyFrom );
+ lcl_extractAndRemove( aArgs, PROPERTY_ACTIVE_CONNECTION, xConnection );
+ lcl_extractAndRemove( aArgs, PROPERTY_AS_TEMPLATE, bAsTemplate );
+ lcl_extractAndRemove( aArgs, INFO_MEDIATYPE, sMediaType );
+ lcl_extractAndRemove( aArgs, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentServiceName" ) ), sDocServiceName );
+
+ // ClassID has two allowed types, so a special treatment here
+ Any aClassIDArg = aArgs.get( "ClassID" );
+ if ( aClassIDArg.hasValue() )
+ {
+ if ( !( aClassIDArg >>= aClassID ) )
+ {
+ // Extended for usage also with a string
+ ::rtl::OUString sClassIDString;
+ if ( !( aClassIDArg >>= sClassIDString ) )
+ throw IllegalArgumentException( ::rtl::OUString(), *this, 2 );
+
+ aClassID = ::comphelper::MimeConfigurationHelper::GetSequenceClassIDRepresentation( sClassIDString );
+ }
+
+#if OSL_DEBUG_LEVEL > 0
+ ::rtl::OUString sClassIDString = ::comphelper::MimeConfigurationHelper::GetStringClassIDRepresentation( aClassID );
+ (void)sClassIDString;
+#endif
+ aArgs.remove( "ClassID" );
+ }
+ // Everything which now is still present in the arguments is passed to the embedded object
+ const Sequence< PropertyValue > aCreationArgs( aArgs.getPropertyValues() );
+
+ const ODefinitionContainer_Impl& rDefinitions( getDefinitions() );
+ sal_Bool bNew = ( 0 == sPersistentName.getLength() );
+ if ( bNew )
+ {
+ const static ::rtl::OUString sBaseName(RTL_CONSTASCII_USTRINGPARAM("Obj"));
+
+ sPersistentName = sBaseName;
+ sPersistentName += ::rtl::OUString::valueOf(sal_Int32(rDefinitions.size() + 1));
+ Reference<XNameAccess> xElements(getContainerStorage(),UNO_QUERY);
+ if ( xElements.is() )
+ sPersistentName = ::dbtools::createUniqueName(xElements,sPersistentName);
+
+ const bool bNeedClassID = ( aClassID.getLength() == 0 ) && ( 0 == sURL.getLength() );
+ if ( xCopyFrom.is() )
+ {
+ Sequence<Any> aIni(2);
+ aIni[0] <<= getContainerStorage();
+ aIni[1] <<= sPersistentName;
+ Command aCommand;
+ aCommand.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("copyTo"));
+ aCommand.Argument <<= aIni;
+
+ xCopyFrom->execute(aCommand,-1,Reference< XCommandEnvironment >());
+ Reference<XPropertySet> xProp(xCopyFrom,UNO_QUERY);
+ if ( xProp.is() && xProp->getPropertySetInfo().is() && xProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_AS_TEMPLATE) )
+ xProp->getPropertyValue(PROPERTY_AS_TEMPLATE) >>= bAsTemplate;
+
+ // if we do not have an own class ID, see if we can determine one from the copy we just created
+ if ( bNeedClassID )
+ ODocumentDefinition::GetDocumentServiceFromMediaType( getContainerStorage(), sPersistentName, m_aContext, aClassID );
+ }
+ else
+ {
+ if ( bNeedClassID )
+ {
+ if ( sMediaType.getLength() )
+ ODocumentDefinition::GetDocumentServiceFromMediaType( sMediaType, m_aContext, aClassID );
+ else if ( sDocServiceName.getLength() )
+ {
+ ::comphelper::MimeConfigurationHelper aConfigHelper( m_aContext.getLegacyServiceFactory() );
+ const Sequence< NamedValue > aProps( aConfigHelper.GetObjectPropsByDocumentName( sDocServiceName ) );
+ const ::comphelper::NamedValueCollection aMediaTypeProps( aProps );
+ aClassID = aMediaTypeProps.getOrDefault( "ClassID", Sequence< sal_Int8 >() );
+ }
+ }
+ }
+ }
+
+ ODefinitionContainer_Impl::const_iterator aFind = rDefinitions.find( sName );
+ TContentPtr pElementImpl;
+ if ( bNew || ( aFind == rDefinitions.end() ) )
+ {
+ pElementImpl.reset( new OContentHelper_Impl );
+ if ( !bNew )
+ pElementImpl->m_aProps.aTitle = sName;
+
+ pElementImpl->m_aProps.sPersistentName = sPersistentName;
+ pElementImpl->m_aProps.bAsTemplate = bAsTemplate;
+ pElementImpl->m_pDataSource = m_pImpl->m_pDataSource;
+ }
+ else
+ pElementImpl = aFind->second;
+
+ ::rtl::Reference< ODocumentDefinition > pDocDef = new ODocumentDefinition( *this, m_aContext.getLegacyServiceFactory(), pElementImpl, m_bFormsContainer );
+ if ( aClassID.getLength() )
+ {
+ pDocDef->initialLoad( aClassID, aCreationArgs, xConnection );
+ }
+ else
+ {
+ OSL_ENSURE( aCreationArgs.getLength() == 0, "ODocumentContainer::createInstance: additional creation args are lost, if you do not provide a class ID." );
+ }
+ xContent = pDocDef.get();
+
+ if ( sURL.getLength() )
+ {
+ Sequence<Any> aIni(2);
+ aIni[0] <<= sURL;
+ Command aCommand;
+ aCommand.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("insert"));
+ aCommand.Argument <<= aIni;
+ Reference< XCommandProcessor > xCommandProcessor(xContent,UNO_QUERY);
+ if ( xContent.is() )
+ {
+ xCommandProcessor->execute(aCommand,-1,Reference< XCommandEnvironment >());
+ }
+ }
+ }
+ else if ( ServiceSpecifier == SERVICE_NAME_FORM_COLLECTION || SERVICE_NAME_REPORT_COLLECTION == ServiceSpecifier )
+ {
+ const Any* pBegin = _aArguments.getConstArray();
+ const Any* pEnd = pBegin + _aArguments.getLength();
+ PropertyValue aValue;
+ ::rtl::OUString sName;
+ Reference<XNameAccess> xCopyFrom;
+ for(;pBegin != pEnd;++pBegin)
+ {
+ *pBegin >>= aValue;
+ if ( aValue.Name.equalsAscii(PROPERTY_NAME) )
+ {
+ aValue.Value >>= sName;
+ }
+ else if ( aValue.Name.equalsAscii(PROPERTY_EMBEDDEDOBJECT) )
+ {
+ xCopyFrom.set(aValue.Value,UNO_QUERY);
+ }
+ }
+ OSL_ENSURE(sName.getLength(),"Invalid name for a document container!");
+ const ODefinitionContainer_Impl& rDefinitions( getDefinitions() );
+ ODefinitionContainer_Impl::const_iterator aFind = rDefinitions.find( sName );
+ TContentPtr pElementImpl;
+ if ( aFind == rDefinitions.end() )
+ {
+ pElementImpl.reset(new ODefinitionContainer_Impl);
+ pElementImpl->m_aProps.aTitle = sName;
+ pElementImpl->m_pDataSource = m_pImpl->m_pDataSource;
+ }
+ else
+ pElementImpl = aFind->second;
+ OSL_ENSURE( pElementImpl ," Invalid entry in map!");
+ xContent = new ODocumentContainer( m_aContext.getLegacyServiceFactory(), *this, pElementImpl, ServiceSpecifier == SERVICE_NAME_FORM_COLLECTION );
+
+ // copy children
+ if ( xCopyFrom.is() )
+ {
+ Sequence< ::rtl::OUString> aSeq = xCopyFrom->getElementNames();
+ const ::rtl::OUString* elements = aSeq.getConstArray();
+ const ::rtl::OUString* elementsEnd = elements + aSeq.getLength();
+ Reference<XContent> xObjectToCopy;
+
+ Reference<XMultiServiceFactory> xORB(xContent,UNO_QUERY);
+ OSL_ENSURE(xORB.is(),"No service factory given");
+ if ( xORB.is() )
+ {
+ for(;elements != elementsEnd;++elements)
+ {
+ xCopyFrom->getByName(*elements) >>= xObjectToCopy;
+ Sequence< Any > aArguments(3);
+ PropertyValue aArgument;
+ // set as folder
+ aArgument.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Name"));
+ aArgument.Value <<= *elements;
+ aArguments[0] <<= aArgument;
+ //parent
+ aArgument.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Parent"));
+ aArgument.Value <<= xContent;
+ aArguments[1] <<= aArgument;
+
+ aArgument.Name = PROPERTY_EMBEDDEDOBJECT;
+ aArgument.Value <<= xObjectToCopy;
+ aArguments[2] <<= aArgument;
+
+ ::rtl::OUString sServiceName;
+ if ( Reference< XNameAccess >( xObjectToCopy, UNO_QUERY ).is() )
+ {
+ if ( m_bFormsContainer )
+ sServiceName = SERVICE_NAME_FORM_COLLECTION;
+ else
+ sServiceName = SERVICE_NAME_REPORT_COLLECTION;
+ }
+ else
+ sServiceName = SERVICE_SDB_DOCUMENTDEFINITION;
+
+ Reference<XContent > xNew(xORB->createInstanceWithArguments(sServiceName,aArguments),UNO_QUERY);
+ Reference<XNameContainer> xNameContainer(xContent,UNO_QUERY);
+ if ( xNameContainer.is() )
+ xNameContainer->insertByName(*elements,makeAny(xNew));
+ }
+ }
+ }
+ }
+ xRet = xContent;
+ return xRet;
+}
+
+Sequence< ::rtl::OUString > SAL_CALL ODocumentContainer::getAvailableServiceNames( ) throw (RuntimeException)
+{
+ Sequence< ::rtl::OUString > aSe(3);
+ aSe[0] = SERVICE_SDB_DOCUMENTDEFINITION;
+ aSe[1] = SERVICE_NAME_FORM_COLLECTION;
+ aSe[2] = SERVICE_NAME_REPORT_COLLECTION;
+ return aSe;
+}
+
+Any SAL_CALL ODocumentContainer::execute( const Command& aCommand, sal_Int32 CommandId, const Reference< XCommandEnvironment >& Environment ) throw (Exception, CommandAbortedException, RuntimeException)
+{
+ Any aRet;
+ if ( aCommand.Name.compareToAscii( "open" ) == 0 )
+ {
+ //////////////////////////////////////////////////////////////////
+ // open command for a folder content
+ //////////////////////////////////////////////////////////////////
+ OpenCommandArgument2 aOpenCommand;
+ if ( !( aCommand.Argument >>= aOpenCommand ) )
+ {
+ OSL_ENSURE( sal_False, "Wrong argument type!" );
+ ucbhelper::cancelCommandExecution(
+ makeAny( IllegalArgumentException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+ sal_Bool bOpenFolder =
+ ( ( aOpenCommand.Mode == OpenMode::ALL ) ||
+ ( aOpenCommand.Mode == OpenMode::FOLDERS ) ||
+ ( aOpenCommand.Mode == OpenMode::DOCUMENTS ) );
+
+ if ( bOpenFolder )
+ {
+ // open as folder - return result set
+
+ Reference< XDynamicResultSet > xSet
+ = new DynamicResultSet( m_aContext.getLegacyServiceFactory(),
+ this,
+ aOpenCommand,
+ Environment );
+ aRet <<= xSet;
+ }
+ else
+ {
+ // Unsupported.
+ ucbhelper::cancelCommandExecution(
+ makeAny( UnsupportedOpenModeException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ sal_Int16( aOpenCommand.Mode ) ) ),
+ Environment );
+ // Unreachable
+ }
+ }
+ else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "insert" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // insert
+ //////////////////////////////////////////////////////////////////
+
+ InsertCommandArgument arg;
+ if ( !( aCommand.Argument >>= arg ) )
+ {
+ OSL_ENSURE( sal_False, "Wrong argument type!" );
+ ucbhelper::cancelCommandExecution(
+ makeAny( IllegalArgumentException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+ }
+ else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "delete" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // delete
+ //////////////////////////////////////////////////////////////////
+ Sequence< ::rtl::OUString> aSeq = getElementNames();
+ const ::rtl::OUString* pIter = aSeq.getConstArray();
+ const ::rtl::OUString* pEnd = pIter + aSeq.getLength();
+ for(;pIter != pEnd;++pIter)
+ removeByName(*pIter);
+
+ dispose();
+ }
+ else
+ aRet = OContentHelper::execute(aCommand,CommandId,Environment);
+ return aRet;
+}
+
+namespace
+{
+ sal_Bool lcl_queryContent(const ::rtl::OUString& _sName,Reference< XNameContainer >& _xNameContainer,Any& _rRet,::rtl::OUString& _sSimpleName)
+ {
+ sal_Bool bRet = sal_False;
+ sal_Int32 nIndex = 0;
+ ::rtl::OUString sName = _sName.getToken(0,'/',nIndex);
+ bRet = _xNameContainer->hasByName(sName);
+ if ( bRet )
+ {
+ _rRet = _xNameContainer->getByName(_sSimpleName = sName);
+ while ( nIndex != -1 && bRet )
+ {
+ sName = _sName.getToken(0,'/',nIndex);
+ _xNameContainer.set(_rRet,UNO_QUERY);
+ bRet = _xNameContainer.is();
+ if ( bRet )
+ {
+ bRet = _xNameContainer->hasByName(sName);
+ _sSimpleName = sName;
+ if ( bRet )
+ _rRet = _xNameContainer->getByName(sName);
+ }
+ }
+ }
+ if ( nIndex == -1 )
+ _sSimpleName = sName; // a content
+ else
+ _xNameContainer.clear(); // a sub folder doesn't exist
+ return bRet;
+ }
+}
+
+Reference< XComponent > SAL_CALL ODocumentContainer::loadComponentFromURL( const ::rtl::OUString& _sURL
+ , const ::rtl::OUString& /*TargetFrameName*/
+ , sal_Int32 /*SearchFlags*/
+ , const Sequence< PropertyValue >& Arguments ) throw (IOException, IllegalArgumentException, RuntimeException)
+{
+ ::SolarMutexGuard aSolarGuard;
+
+ MutexGuard aGuard(m_aMutex);
+ Reference< XComponent > xComp;
+ try
+ {
+ Any aContent;
+ Reference< XNameContainer > xNameContainer(this);
+ ::rtl::OUString sName;
+ if ( !lcl_queryContent(_sURL,xNameContainer,aContent,sName) )
+ {
+ ::rtl::OUString sMessage( DBA_RES( RID_STR_NAME_NOT_FOUND ) );
+ ::comphelper::string::searchAndReplaceAsciiI( sMessage, "$name$", _sURL );
+ throw IllegalArgumentException( sMessage, *this, 1 );
+ }
+
+ Reference< XCommandProcessor > xContent(aContent,UNO_QUERY);
+ if ( xContent.is() )
+ {
+ Command aCommand;
+
+ ::comphelper::NamedValueCollection aArgs( Arguments );
+ aCommand.Name = aArgs.getOrDefault( "OpenMode", ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ) );
+ aArgs.remove( "OpenMode" );
+
+ OpenCommandArgument2 aOpenCommand;
+ aOpenCommand.Mode = OpenMode::DOCUMENT;
+ aArgs.put( "OpenCommandArgument", aOpenCommand );
+
+ aCommand.Argument <<= aArgs.getPropertyValues();
+ xComp.set(xContent->execute(aCommand,xContent->createCommandIdentifier(),Reference< XCommandEnvironment >()),UNO_QUERY);
+ }
+ }
+ catch(NoSuchElementException)
+ {
+ throw IllegalArgumentException();
+ }
+ catch(WrappedTargetException e)
+ {
+ // throw IllegalArgumentException();
+ throw;
+ }
+ return xComp;
+}
+
+Any SAL_CALL ODocumentContainer::getByHierarchicalName( const ::rtl::OUString& _sName ) throw (NoSuchElementException, RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ Any aContent;
+ Reference< XNameContainer > xNameContainer(this);
+ ::rtl::OUString sName;
+ if ( lcl_queryContent(_sName,xNameContainer,aContent,sName) )
+ return aContent;
+ throw NoSuchElementException(_sName,*this);
+}
+
+sal_Bool SAL_CALL ODocumentContainer::hasByHierarchicalName( const ::rtl::OUString& _sName ) throw (RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ Any aContent;
+ Reference< XNameContainer > xNameContainer(this);
+ ::rtl::OUString sName;
+ return lcl_queryContent(_sName,xNameContainer,aContent,sName);
+}
+
+// XHierarchicalNameContainer
+void SAL_CALL ODocumentContainer::insertByHierarchicalName( const ::rtl::OUString& _sName, const Any& _aElement ) throw (IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
+{
+ Reference< XContent > xContent(_aElement,UNO_QUERY);
+ if ( !xContent.is() )
+ throw IllegalArgumentException();
+
+ ClearableMutexGuard aGuard(m_aMutex);
+ Any aContent;
+ Reference< XNameContainer > xNameContainer(this);
+ ::rtl::OUString sName;
+ if ( lcl_queryContent(_sName,xNameContainer,aContent,sName) )
+ throw ElementExistException(_sName,*this);
+
+ if ( !xNameContainer.is() )
+ {
+ ::rtl::OUString sMessage( DBA_RES( RID_STR_NO_SUB_FOLDER ) );
+ sal_Int32 index = sName.getLength();
+ ::comphelper::string::searchAndReplaceAsciiI( sMessage, "$folder$", _sName.getToken(0,'/',index) );
+ throw IllegalArgumentException( sMessage, *this, 1 );
+ }
+
+ xNameContainer->insertByName(sName,_aElement);
+}
+
+void SAL_CALL ODocumentContainer::removeByHierarchicalName( const ::rtl::OUString& _sName ) throw (NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ if ( !_sName.getLength() )
+ throw NoSuchElementException(_sName,*this);
+
+ ClearableMutexGuard aGuard(m_aMutex);
+ Any aContent;
+ ::rtl::OUString sName;
+ Reference< XNameContainer > xNameContainer(this);
+ if ( !lcl_queryContent(_sName,xNameContainer,aContent,sName) )
+ throw NoSuchElementException(_sName,*this);
+
+ xNameContainer->removeByName(sName);
+}
+
+// XHierarchicalNameReplace
+void SAL_CALL ODocumentContainer::replaceByHierarchicalName( const ::rtl::OUString& _sName, const Any& _aElement ) throw (IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ Reference< XContent > xContent(_aElement,UNO_QUERY);
+ if ( !xContent.is() )
+ throw IllegalArgumentException();
+
+ ClearableMutexGuard aGuard(m_aMutex);
+ Any aContent;
+ ::rtl::OUString sName;
+ Reference< XNameContainer > xNameContainer(this);
+ if ( !lcl_queryContent(_sName,xNameContainer,aContent,sName) )
+ throw NoSuchElementException(_sName,*this);
+
+ xNameContainer->replaceByName(sName,_aElement);
+}
+
+::rtl::OUString SAL_CALL ODocumentContainer::getHierarchicalName() throw (RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ return impl_getHierarchicalName( false );
+}
+
+::rtl::OUString SAL_CALL ODocumentContainer::composeHierarchicalName( const ::rtl::OUString& i_rRelativeName ) throw (IllegalArgumentException, NoSupportException, RuntimeException)
+{
+ ::rtl::OUStringBuffer aBuffer;
+ aBuffer.append( getHierarchicalName() );
+ aBuffer.append( sal_Unicode( '/' ) );
+ aBuffer.append( i_rRelativeName );
+ return aBuffer.makeStringAndClear();
+}
+
+::rtl::Reference<OContentHelper> ODocumentContainer::getContent(const ::rtl::OUString& _sName) const
+{
+ ::rtl::Reference<OContentHelper> pContent = NULL;
+ try
+ {
+ Reference<XUnoTunnel> xUnoTunnel(const_cast<ODocumentContainer*>(this)->implGetByName( _sName, sal_True ), UNO_QUERY );
+ if ( xUnoTunnel.is() )
+ pContent = reinterpret_cast<OContentHelper*>(xUnoTunnel->getSomething(OContentHelper::getUnoTunnelImplementationId()));
+ }
+ catch(Exception)
+ {
+ }
+ return pContent;
+}
+
+void ODocumentContainer::getPropertyDefaultByHandle( sal_Int32 /*_nHandle*/, Any& _rDefault ) const
+{
+ _rDefault.clear();
+}
+
+void SAL_CALL ODocumentContainer::commit( ) throw (::com::sun::star::io::IOException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ Documents::iterator aIter = m_aDocumentMap.begin();
+ Documents::iterator aEnd = m_aDocumentMap.end();
+ for (; aIter != aEnd ; ++aIter)
+ {
+ Reference<XTransactedObject> xTrans(aIter->second.get(),UNO_QUERY);
+ if ( xTrans.is() )
+ xTrans->commit();
+ }
+ Reference<XTransactedObject> xTrans(getContainerStorage(),UNO_QUERY);
+ if ( xTrans.is() )
+ xTrans->commit();
+}
+
+void SAL_CALL ODocumentContainer::revert( ) throw (::com::sun::star::io::IOException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ Documents::iterator aIter = m_aDocumentMap.begin();
+ Documents::iterator aEnd = m_aDocumentMap.end();
+ for (; aIter != aEnd ; ++aIter)
+ {
+ Reference<XTransactedObject> xTrans(aIter->second.get(),UNO_QUERY);
+ if ( xTrans.is() )
+ xTrans->revert();
+ }
+ Reference<XTransactedObject> xTrans(getContainerStorage(),UNO_QUERY);
+ if ( xTrans.is() )
+ xTrans->revert();
+}
+
+Reference< XStorage> ODocumentContainer::getContainerStorage() const
+{
+ return m_pImpl->m_pDataSource
+ ? m_pImpl->m_pDataSource->getStorage( m_bFormsContainer ? ODatabaseModelImpl::E_FORM : ODatabaseModelImpl::E_REPORT )
+ : Reference< XStorage>();
+}
+
+void SAL_CALL ODocumentContainer::removeByName( const ::rtl::OUString& _rName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ ResettableMutexGuard aGuard(m_aMutex);
+
+ // check the arguments
+ if (!_rName.getLength())
+ throw IllegalArgumentException();
+
+ if (!checkExistence(_rName))
+ throw NoSuchElementException(_rName,*this);
+
+ Reference< XCommandProcessor > xContent( implGetByName( _rName, sal_True ), UNO_QUERY );
+ if ( xContent.is() )
+ {
+ Command aCommand;
+
+ aCommand.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("delete"));
+ xContent->execute(aCommand,xContent->createCommandIdentifier(),Reference< XCommandEnvironment >());
+ }
+
+ // do the removal
+ implRemove(_rName);
+
+ // disposeComponent(xContent); // no dispose here, the object may be inserted again under a different name
+
+ notifyByName( aGuard, _rName, NULL, NULL, E_REMOVED, ContainerListemers );
+}
+
+void SAL_CALL ODocumentContainer::rename( const ::rtl::OUString& newName ) throw (SQLException, ElementExistException, RuntimeException)
+{
+ try
+ {
+ osl::ClearableGuard< osl::Mutex > aGuard(m_aMutex);
+ if ( newName.equals( m_pImpl->m_aProps.aTitle ) )
+ return;
+
+ sal_Int32 nHandle = PROPERTY_ID_NAME;
+ Any aOld = makeAny(m_pImpl->m_aProps.aTitle);
+ Any aNew = makeAny(newName);
+
+ aGuard.clear();
+ fire(&nHandle, &aNew, &aOld, 1, sal_True );
+ m_pImpl->m_aProps.aTitle = newName;
+ fire(&nHandle, &aNew, &aOld, 1, sal_False );
+ }
+ catch(const PropertyVetoException&)
+ {
+ throw ElementExistException(newName,*this);
+ }
+}
+
+} // namespace dbaccess
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/documentcontainer.hxx b/dbaccess/source/core/dataaccess/documentcontainer.hxx
new file mode 100644
index 000000000000..ffcdff6c9c19
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/documentcontainer.hxx
@@ -0,0 +1,146 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _DBA_COREDATAACCESS_DOCUMENTCONTAINER_HXX_
+#define _DBA_COREDATAACCESS_DOCUMENTCONTAINER_HXX_
+
+#include "definitioncontainer.hxx"
+#include <cppuhelper/implbase5.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/frame/XComponentLoader.hpp>
+#include <com/sun/star/container/XHierarchicalNameContainer.hpp>
+#include <com/sun/star/container/XHierarchicalName.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <comphelper/propertystatecontainer.hxx>
+#include <comphelper/proparrhlp.hxx>
+#include "apitools.hxx"
+
+namespace dbaccess
+{
+typedef ::cppu::ImplHelper5 < ::com::sun::star::frame::XComponentLoader
+ , ::com::sun::star::lang::XMultiServiceFactory
+ , ::com::sun::star::container::XHierarchicalNameContainer
+ , ::com::sun::star::container::XHierarchicalName
+ , ::com::sun::star::embed::XTransactedObject
+ > ODocumentContainer_Base;
+//==========================================================================
+//= ODocumentContainer - collections of database documents (reports/forms)
+//==========================================================================
+class ODocumentContainer : public ODefinitionContainer
+ , public ODocumentContainer_Base
+ , public ::comphelper::OPropertyStateContainer
+ , public ::comphelper::OPropertyArrayUsageHelper< ODocumentContainer >
+{
+ sal_Bool m_bFormsContainer;
+
+public:
+ /** constructs the container.<BR>
+ */
+ ODocumentContainer(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _xORB
+ , const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _xParentContainer
+ ,const TContentPtr& _pImpl
+ , sal_Bool _bFormsContainer
+ );
+
+ // ::com::sun::star::uno::XInterface
+ DECLARE_XINTERFACE( )
+ // com::sun::star::lang::XTypeProvider
+ DECLARE_TYPEPROVIDER( );
+ // ::com::sun::star::lang::XServiceInfo
+ DECLARE_SERVICE_INFO();
+
+ // XComponentLoader
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > SAL_CALL loadComponentFromURL( const ::rtl::OUString& URL, const ::rtl::OUString& TargetFrameName, sal_Int32 SearchFlags, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& Arguments ) throw (::com::sun::star::io::IOException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::lang::XMultiServiceFactory
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL createInstance( const ::rtl::OUString& aServiceSpecifier ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL createInstanceWithArguments( const ::rtl::OUString& ServiceSpecifier, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& Arguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getAvailableServiceNames( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XCommandProcessor
+ virtual ::com::sun::star::uno::Any SAL_CALL execute( const ::com::sun::star::ucb::Command& aCommand, sal_Int32 CommandId, const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >& Environment ) throw (::com::sun::star::uno::Exception, ::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::RuntimeException) ;
+
+ // XHierarchicalNameAccess
+ virtual ::com::sun::star::uno::Any SAL_CALL getByHierarchicalName( const ::rtl::OUString& _sName ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasByHierarchicalName( const ::rtl::OUString& _sName ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XHierarchicalNameContainer
+ virtual void SAL_CALL insertByHierarchicalName( const ::rtl::OUString& aName, const ::com::sun::star::uno::Any& aElement ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeByHierarchicalName( const ::rtl::OUString& Name ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+ // XHierarchicalName
+ virtual ::rtl::OUString SAL_CALL getHierarchicalName( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL composeHierarchicalName( const ::rtl::OUString& aRelativeName ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException);
+
+ // XNameContainer
+ virtual void SAL_CALL removeByName( const ::rtl::OUString& _rName ) throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+ // XHierarchicalNameReplace
+ virtual void SAL_CALL replaceByHierarchicalName( const ::rtl::OUString& aName, const ::com::sun::star::uno::Any& aElement ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::beans::XPropertySet
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) throw(::com::sun::star::uno::RuntimeException);
+
+ // XTransactedObject
+ virtual void SAL_CALL commit( ) throw (::com::sun::star::io::IOException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL revert( ) throw (::com::sun::star::io::IOException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+ // XRename
+ virtual void SAL_CALL rename( const ::rtl::OUString& newName ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException);
+
+ // OPropertySetHelper
+ virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
+
+ // helper
+ ::rtl::Reference<OContentHelper> getContent(const ::rtl::OUString& _sName) const;
+ ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > getContainerStorage() const;
+
+protected:
+ virtual ~ODocumentContainer();
+
+ /** OContentHelper
+ */
+ virtual ::rtl::OUString determineContentType() const;
+
+ // ODefinitionContainer
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContent > createObject(
+ const ::rtl::OUString& _rName
+ );
+
+ virtual void getPropertyDefaultByHandle( sal_Int32 _nHandle, ::com::sun::star::uno::Any& _rDefault ) const;
+
+ // OPropertyArrayUsageHelper
+ virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;
+};
+
+} // namespace dbaccess
+
+#endif // _DBA_COREDATAACCESS_DOCUMENTCONTAINER_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/documentdefinition.cxx b/dbaccess/source/core/dataaccess/documentdefinition.cxx
new file mode 100644
index 000000000000..4bd8c8edfc72
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/documentdefinition.cxx
@@ -0,0 +1,2211 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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"
+
+#include "documentdefinition.hxx"
+#include "dbastrings.hrc"
+#include "sdbcoretools.hxx"
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+#include <comphelper/property.hxx>
+#include <comphelper/sequence.hxx>
+#include <comphelper/mediadescriptor.hxx>
+#include <comphelper/namedvaluecollection.hxx>
+#include <comphelper/classids.hxx>
+#include <com/sun/star/frame/XUntitledNumbers.hpp>
+#include <com/sun/star/awt/XTopWindow.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/frame/XTitle.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/task/XJobExecutor.hpp>
+#include <com/sun/star/frame/XDispatchProviderInterception.hpp>
+#include <com/sun/star/frame/XFramesSupplier.hpp>
+#include <com/sun/star/ucb/InsertCommandArgument.hpp>
+#include <com/sun/star/report/XReportDefinition.hpp>
+#include <com/sun/star/report/XReportEngine.hpp>
+#include <com/sun/star/ucb/OpenMode.hpp>
+#include <com/sun/star/embed/XEmbedObjectFactory.hpp>
+#include <com/sun/star/embed/XEmbedObjectCreator.hpp>
+#include <com/sun/star/embed/Aspects.hpp>
+#include <ucbhelper/cancelcommandexecution.hxx>
+#include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
+#include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/embed/XEmbedPersist.hpp>
+#include <com/sun/star/embed/EmbedStates.hpp>
+#include <com/sun/star/embed/XComponentSupplier.hpp>
+#include <com/sun/star/embed/EntryInitModes.hpp>
+#include <com/sun/star/ucb/MissingPropertiesException.hpp>
+#include <com/sun/star/ucb/MissingInputStreamException.hpp>
+#include <com/sun/star/ucb/OpenCommandArgument2.hpp>
+#include <com/sun/star/util/XCloseBroadcaster.hpp>
+#include <com/sun/star/frame/XModule.hpp>
+#include <com/sun/star/datatransfer/DataFlavor.hpp>
+#include <com/sun/star/datatransfer/XTransferable.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/embed/XCommonEmbedPersist.hpp>
+#include "intercept.hxx"
+#include <com/sun/star/sdb/ErrorCondition.hpp>
+#include <com/sun/star/sdb/XInteractionDocumentSave.hpp>
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <com/sun/star/sdb/DocumentSaveRequest.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+#include <com/sun/star/document/MacroExecMode.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/form/XFormsSupplier.hpp>
+#include <com/sun/star/form/XForm.hpp>
+#include <comphelper/interaction.hxx>
+#include <connectivity/dbtools.hxx>
+#include <vcl/svapp.hxx>
+#include <osl/mutex.hxx>
+#include <sal/macros.h>
+#include <com/sun/star/view/XViewSettingsSupplier.hpp>
+#include "core_resource.hxx"
+#include "core_resource.hrc"
+#include "datasource.hxx"
+#include <com/sun/star/embed/XStateChangeBroadcaster.hpp>
+#include <com/sun/star/task/XInteractionApprove.hpp>
+#include <com/sun/star/task/XInteractionDisapprove.hpp>
+#include <com/sun/star/frame/XLayoutManager.hpp>
+#include <cppuhelper/compbase1.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#include <comphelper/sequenceashashmap.hxx>
+#include <comphelper/mimeconfighelper.hxx>
+#include <comphelper/storagehelper.hxx>
+#include <com/sun/star/container/XContentEnumerationAccess.hpp>
+#include <com/sun/star/io/WrongFormatException.hpp>
+#include <com/sun/star/sdb/application/XDatabaseDocumentUI.hpp>
+#include <com/sun/star/sdb/application/DatabaseObject.hpp>
+#include <com/sun/star/util/XModifiable2.hpp>
+
+using namespace ::com::sun::star;
+using namespace view;
+using namespace uno;
+using namespace util;
+using namespace ucb;
+using namespace beans;
+using namespace lang;
+using namespace awt;
+using namespace embed;
+using namespace frame;
+using namespace document;
+using namespace sdbc;
+using namespace sdb;
+using namespace io;
+using namespace container;
+using namespace datatransfer;
+using namespace task;
+using namespace form;
+using namespace drawing;
+using namespace ::osl;
+using namespace ::comphelper;
+using namespace ::cppu;
+namespace css = ::com::sun::star;
+
+using sdb::application::XDatabaseDocumentUI;
+namespace DatabaseObject = sdb::application::DatabaseObject;
+
+
+#define DEFAULT_WIDTH 10000
+#define DEFAULT_HEIGHT 7500
+
+namespace dbaccess
+{
+
+ typedef ::boost::optional< bool > optional_bool;
+
+ //=========================================================================
+ //= helper
+ //=========================================================================
+ namespace
+ {
+ // --------------------------------------------------------------------
+ ::rtl::OUString lcl_determineContentType_nothrow( const Reference< XStorage >& _rxContainerStorage,
+ const ::rtl::OUString& _rEntityName )
+ {
+ ::rtl::OUString sContentType;
+ try
+ {
+ Reference< XStorage > xContainerStorage( _rxContainerStorage, UNO_QUERY_THROW );
+ ::utl::SharedUNOComponent< XPropertySet > xStorageProps(
+ xContainerStorage->openStorageElement( _rEntityName, ElementModes::READ ), UNO_QUERY_THROW );
+ OSL_VERIFY( xStorageProps->getPropertyValue( INFO_MEDIATYPE ) >>= sContentType );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return sContentType;
+ }
+ }
+
+ //==================================================================
+ // OEmbedObjectHolder
+ //==================================================================
+ typedef ::cppu::WeakComponentImplHelper1< embed::XStateChangeListener > TEmbedObjectHolder;
+ class OEmbedObjectHolder : public ::comphelper::OBaseMutex
+ ,public TEmbedObjectHolder
+ {
+ Reference< XEmbeddedObject > m_xBroadCaster;
+ ODocumentDefinition* m_pDefinition;
+ bool m_bInStateChange;
+ bool m_bInChangingState;
+ protected:
+ virtual void SAL_CALL disposing();
+ public:
+ OEmbedObjectHolder(const Reference< XEmbeddedObject >& _xBroadCaster,ODocumentDefinition* _pDefinition)
+ : TEmbedObjectHolder(m_aMutex)
+ ,m_xBroadCaster(_xBroadCaster)
+ ,m_pDefinition(_pDefinition)
+ ,m_bInStateChange(false)
+ ,m_bInChangingState(false)
+ {
+ osl_incrementInterlockedCount( &m_refCount );
+ {
+ if ( m_xBroadCaster.is() )
+ m_xBroadCaster->addStateChangeListener(this);
+ }
+ osl_decrementInterlockedCount( &m_refCount );
+ }
+
+ virtual void SAL_CALL changingState( const lang::EventObject& aEvent, ::sal_Int32 nOldState, ::sal_Int32 nNewState ) throw (embed::WrongStateException, uno::RuntimeException);
+ virtual void SAL_CALL stateChanged( const lang::EventObject& aEvent, ::sal_Int32 nOldState, ::sal_Int32 nNewState ) throw (uno::RuntimeException);
+ virtual void SAL_CALL disposing( const lang::EventObject& Source ) throw (uno::RuntimeException);
+ };
+
+ void SAL_CALL OEmbedObjectHolder::disposing()
+ {
+ if ( m_xBroadCaster.is() )
+ m_xBroadCaster->removeStateChangeListener(this);
+ m_xBroadCaster = NULL;
+ m_pDefinition = NULL;
+ }
+
+ void SAL_CALL OEmbedObjectHolder::changingState( const lang::EventObject& /*aEvent*/, ::sal_Int32 nOldState, ::sal_Int32 nNewState ) throw (embed::WrongStateException, uno::RuntimeException)
+ {
+ if ( !m_bInChangingState && nNewState == EmbedStates::RUNNING && nOldState == EmbedStates::ACTIVE && m_pDefinition )
+ {
+ m_bInChangingState = true;
+ //m_pDefinition->save(sal_False);
+ m_bInChangingState = false;
+ }
+ }
+
+ void SAL_CALL OEmbedObjectHolder::stateChanged( const lang::EventObject& aEvent, ::sal_Int32 nOldState, ::sal_Int32 nNewState ) throw (uno::RuntimeException)
+ {
+ if ( !m_bInStateChange && nNewState == EmbedStates::RUNNING && nOldState == EmbedStates::ACTIVE && m_pDefinition )
+ {
+ m_bInStateChange = true;
+ Reference<XInterface> xInt(static_cast< ::cppu::OWeakObject* >(m_pDefinition),UNO_QUERY);
+ {
+ Reference<XEmbeddedObject> xEmbeddedObject(aEvent.Source,UNO_QUERY);
+ if ( xEmbeddedObject.is() )
+ xEmbeddedObject->changeState(EmbedStates::LOADED);
+ }
+ m_bInStateChange = false;
+ }
+ }
+
+ void SAL_CALL OEmbedObjectHolder::disposing( const lang::EventObject& /*Source*/ ) throw (uno::RuntimeException)
+ {
+ m_xBroadCaster = NULL;
+ }
+
+ //==================================================================
+ // OEmbeddedClientHelper
+ //==================================================================
+ typedef ::cppu::WeakImplHelper1 < XEmbeddedClient
+ > EmbeddedClientHelper_BASE;
+ class OEmbeddedClientHelper : public EmbeddedClientHelper_BASE
+ {
+ ODocumentDefinition* m_pClient;
+ public:
+ OEmbeddedClientHelper(ODocumentDefinition* _pClient) :m_pClient(_pClient) {}
+
+ virtual void SAL_CALL saveObject( ) throw (ObjectSaveVetoException, Exception, RuntimeException)
+ {
+ }
+ virtual void SAL_CALL onShowWindow( sal_Bool /*bVisible*/ ) throw (RuntimeException)
+ {
+ }
+ // XComponentSupplier
+ virtual Reference< util::XCloseable > SAL_CALL getComponent( ) throw (RuntimeException)
+ {
+ return Reference< css::util::XCloseable >();
+ }
+
+ // XEmbeddedClient
+ virtual void SAL_CALL visibilityChanged( ::sal_Bool /*bVisible*/ ) throw (WrongStateException, RuntimeException)
+ {
+ }
+ inline void resetClient(ODocumentDefinition* _pClient) { m_pClient = _pClient; }
+ };
+
+ //==================================================================
+ // LockModifiable
+ //==================================================================
+ class LockModifiable
+ {
+ public:
+ LockModifiable( const Reference< XInterface >& i_rModifiable )
+ :m_xModifiable( i_rModifiable, UNO_QUERY )
+ {
+ OSL_ENSURE( m_xModifiable.is(), "LockModifiable::LockModifiable: invalid component!" );
+ if ( m_xModifiable.is() )
+ {
+ if ( !m_xModifiable->isSetModifiedEnabled() )
+ {
+ // somebody already locked that, no need to lock it, again, and no need to unlock it later
+ m_xModifiable.clear();
+ }
+ else
+ {
+ m_xModifiable->disableSetModified();
+ }
+ }
+ }
+
+ ~LockModifiable()
+ {
+ if ( m_xModifiable.is() )
+ m_xModifiable->enableSetModified();
+ }
+
+ private:
+ Reference< XModifiable2 > m_xModifiable;
+ };
+
+ //==================================================================
+ // LifetimeCoupler
+ //==================================================================
+ typedef ::cppu::WeakImplHelper1 < css::lang::XEventListener
+ > LifetimeCoupler_Base;
+ /** helper class which couples the lifetime of a component to the lifetime
+ of another component
+
+ Instances of this class are constructed with two components. The first is
+ simply held by reference, and thus kept alive. The second one is observed
+ for <code>disposing</code> calls - if they occur, i.e. if the component dies,
+ the reference to the first component is cleared.
+
+ This way, you can ensure that a certain component is kept alive as long
+ as a second component is not disposed.
+ */
+ class LifetimeCoupler : public LifetimeCoupler_Base
+ {
+ private:
+ Reference< XInterface > m_xClient;
+
+ public:
+ inline static void couple( const Reference< XInterface >& _rxClient, const Reference< XComponent >& _rxActor )
+ {
+ Reference< css::lang::XEventListener > xEnsureDelete( new LifetimeCoupler( _rxClient, _rxActor ) );
+ }
+
+ private:
+ inline LifetimeCoupler( const Reference< XInterface >& _rxClient, const Reference< XComponent >& _rxActor )
+ :m_xClient( _rxClient )
+ {
+ DBG_ASSERT( _rxActor.is(), "LifetimeCoupler::LifetimeCoupler: this will crash!" );
+ osl_incrementInterlockedCount( &m_refCount );
+ {
+ _rxActor->addEventListener( this );
+ }
+ osl_decrementInterlockedCount( &m_refCount );
+ DBG_ASSERT( m_refCount, "LifetimeCoupler::LifetimeCoupler: the actor is not holding us by hard ref - this won't work!" );
+ }
+
+ virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) throw (RuntimeException);
+ protected:
+ };
+
+ void SAL_CALL LifetimeCoupler::disposing( const css::lang::EventObject& /*Source*/ ) throw (RuntimeException)
+ {
+ m_xClient.clear();
+ }
+
+ //==================================================================
+ // ODocumentSaveContinuation
+ //==================================================================
+ class ODocumentSaveContinuation : public OInteraction< XInteractionDocumentSave >
+ {
+ ::rtl::OUString m_sName;
+ Reference<XContent> m_xParentContainer;
+
+ public:
+ ODocumentSaveContinuation() { }
+
+ inline Reference<XContent> getContent() const { return m_xParentContainer; }
+ inline ::rtl::OUString getName() const { return m_sName; }
+
+ // XInteractionDocumentSave
+ virtual void SAL_CALL setName( const ::rtl::OUString& _sName,const Reference<XContent>& _xParent) throw(RuntimeException);
+ };
+
+ void SAL_CALL ODocumentSaveContinuation::setName( const ::rtl::OUString& _sName,const Reference<XContent>& _xParent) throw(RuntimeException)
+ {
+ m_sName = _sName;
+ m_xParentContainer = _xParent;
+ }
+
+::rtl::OUString ODocumentDefinition::GetDocumentServiceFromMediaType( const Reference< XStorage >& _rxContainerStorage,
+ const ::rtl::OUString& _rEntityName, const ::comphelper::ComponentContext& _rContext,
+ Sequence< sal_Int8 >& _rClassId )
+{
+ return GetDocumentServiceFromMediaType(
+ lcl_determineContentType_nothrow( _rxContainerStorage, _rEntityName ),
+ _rContext, _rClassId );
+}
+
+::rtl::OUString ODocumentDefinition::GetDocumentServiceFromMediaType( const ::rtl::OUString& _rMediaType,
+ const ::comphelper::ComponentContext& _rContext, Sequence< sal_Int8 >& _rClassId )
+{
+ ::rtl::OUString sResult;
+ try
+ {
+ ::comphelper::MimeConfigurationHelper aConfigHelper( _rContext.getLegacyServiceFactory() );
+ sResult = aConfigHelper.GetDocServiceNameFromMediaType( _rMediaType );
+ _rClassId = aConfigHelper.GetSequenceClassIDRepresentation(aConfigHelper.GetExplicitlyRegisteredObjClassID( _rMediaType ));
+ if ( !_rClassId.getLength() && sResult.getLength() )
+ {
+ Reference< XNameAccess > xObjConfig = aConfigHelper.GetObjConfiguration();
+ if ( xObjConfig.is() )
+ {
+ Sequence< ::rtl::OUString > aClassIDs = xObjConfig->getElementNames();
+ for ( sal_Int32 nInd = 0; nInd < aClassIDs.getLength(); nInd++ )
+ {
+ Reference< XNameAccess > xObjectProps;
+ ::rtl::OUString aEntryDocName;
+
+ if ( ( xObjConfig->getByName( aClassIDs[nInd] ) >>= xObjectProps ) && xObjectProps.is()
+ && ( xObjectProps->getByName(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ObjectDocumentServiceName"))
+ ) >>= aEntryDocName )
+ && aEntryDocName.equals( sResult ) )
+ {
+ _rClassId = aConfigHelper.GetSequenceClassIDRepresentation(aClassIDs[nInd]);
+ break;
+ }
+ }
+ }
+ }
+#if OSL_DEBUG_LEVEL > 0
+ // alternative, shorter approach
+ const Sequence< NamedValue > aProps( aConfigHelper.GetObjectPropsByMediaType( _rMediaType ) );
+ const ::comphelper::NamedValueCollection aMediaTypeProps( aProps );
+ const ::rtl::OUString sAlternativeResult = aMediaTypeProps.getOrDefault( "ObjectDocumentServiceName", ::rtl::OUString() );
+ OSL_ENSURE( sAlternativeResult == sResult, "ODocumentDefinition::GetDocumentServiceFromMediaType: failed, this approach is *not* equivalent (1)!" );
+ const Sequence< sal_Int8 > aAlternativeClassID = aMediaTypeProps.getOrDefault( "ClassID", Sequence< sal_Int8 >() );
+ OSL_ENSURE( aAlternativeClassID == _rClassId, "ODocumentDefinition::GetDocumentServiceFromMediaType: failed, this approach is *not* equivalent (2)!" );
+#endif
+ }
+ catch ( Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return sResult;
+}
+
+//==========================================================================
+//= ODocumentDefinition
+//==========================================================================
+DBG_NAME(ODocumentDefinition)
+
+ODocumentDefinition::ODocumentDefinition( const Reference< XInterface >& _rxContainer, const Reference< XMultiServiceFactory >& _xORB,
+ const TContentPtr& _pImpl, sal_Bool _bForm )
+ :OContentHelper(_xORB,_rxContainer,_pImpl)
+ ,OPropertyStateContainer(OContentHelper::rBHelper)
+ ,m_pInterceptor(NULL)
+ ,m_bForm(_bForm)
+ ,m_bOpenInDesign(sal_False)
+ ,m_bInExecute(sal_False)
+ ,m_bRemoveListener(sal_False)
+ ,m_pClientHelper(NULL)
+{
+ DBG_CTOR(ODocumentDefinition, NULL);
+ registerProperties();
+}
+
+void ODocumentDefinition::initialLoad( const Sequence< sal_Int8 >& i_rClassID, const Sequence< PropertyValue >& i_rCreationArgs,
+ const Reference< XConnection >& i_rConnection )
+{
+ OSL_ENSURE( i_rClassID.getLength(), "ODocumentDefinition::initialLoad: illegal class ID!" );
+ if ( !i_rClassID.getLength() )
+ return;
+
+ loadEmbeddedObject( i_rConnection, i_rClassID, i_rCreationArgs, false, false );
+}
+
+ODocumentDefinition::~ODocumentDefinition()
+{
+ DBG_DTOR(ODocumentDefinition, NULL);
+ if ( !OContentHelper::rBHelper.bInDispose && !OContentHelper::rBHelper.bDisposed )
+ {
+ acquire();
+ dispose();
+ }
+
+ if ( m_pInterceptor )
+ {
+ m_pInterceptor->dispose();
+ m_pInterceptor->release();
+ m_pInterceptor = NULL;
+ }
+}
+
+void ODocumentDefinition::closeObject()
+{
+ ::osl::MutexGuard aGuard(m_aMutex);
+ if ( m_xEmbeddedObject.is() )
+ {
+ try
+ {
+ Reference< com::sun::star::util::XCloseable> xCloseable(m_xEmbeddedObject,UNO_QUERY);
+ if ( xCloseable.is() )
+ xCloseable->close(sal_True);
+ }
+ catch(Exception)
+ {
+ }
+ m_xEmbeddedObject = NULL;
+ if ( m_pClientHelper )
+ {
+ m_pClientHelper->resetClient(NULL);
+ m_pClientHelper->release();
+ m_pClientHelper = NULL;
+ }
+ }
+}
+
+void SAL_CALL ODocumentDefinition::disposing()
+{
+ OContentHelper::disposing();
+ ::osl::MutexGuard aGuard(m_aMutex);
+ closeObject();
+ ::comphelper::disposeComponent(m_xListener);
+ if ( m_bRemoveListener )
+ {
+ Reference<util::XCloseable> xCloseable(m_pImpl->m_pDataSource->getModel_noCreate(),UNO_QUERY);
+ if ( xCloseable.is() )
+ xCloseable->removeCloseListener(this);
+ }
+}
+
+IMPLEMENT_TYPEPROVIDER3(ODocumentDefinition,OContentHelper,OPropertyStateContainer,ODocumentDefinition_Base);
+IMPLEMENT_FORWARD_XINTERFACE3( ODocumentDefinition,OContentHelper,OPropertyStateContainer,ODocumentDefinition_Base)
+IMPLEMENT_SERVICE_INFO1(ODocumentDefinition,"com.sun.star.comp.dba.ODocumentDefinition",SERVICE_SDB_DOCUMENTDEFINITION)
+
+void ODocumentDefinition::registerProperties()
+{
+#define REGISTER_PROPERTY( name, location ) \
+ registerProperty( PROPERTY_##name, PROPERTY_ID_##name, PropertyAttribute::READONLY, &location, ::getCppuType( &location ) );
+
+#define REGISTER_PROPERTY_BV( name, location ) \
+ registerProperty( PROPERTY_##name, PROPERTY_ID_##name, PropertyAttribute::CONSTRAINED | PropertyAttribute::BOUND | PropertyAttribute::READONLY, &location, ::getCppuType( &location ) );
+
+ REGISTER_PROPERTY_BV( NAME, m_pImpl->m_aProps.aTitle );
+ REGISTER_PROPERTY ( AS_TEMPLATE, m_pImpl->m_aProps.bAsTemplate );
+ REGISTER_PROPERTY ( PERSISTENT_NAME, m_pImpl->m_aProps.sPersistentName );
+ REGISTER_PROPERTY ( IS_FORM, m_bForm );
+}
+
+void SAL_CALL ODocumentDefinition::getFastPropertyValue( Any& o_rValue, sal_Int32 i_nHandle ) const
+{
+ if ( i_nHandle == PROPERTY_ID_PERSISTENT_PATH )
+ {
+ ::rtl::OUString sPersistentPath;
+ if ( m_pImpl->m_aProps.sPersistentName.getLength() )
+ {
+ ::rtl::OUStringBuffer aBuffer;
+ aBuffer.append( ODatabaseModelImpl::getObjectContainerStorageName( m_bForm ? ODatabaseModelImpl::E_FORM : ODatabaseModelImpl::E_REPORT ) );
+ aBuffer.append( sal_Unicode( '/' ) );
+ aBuffer.append( m_pImpl->m_aProps.sPersistentName );
+ sPersistentPath = aBuffer.makeStringAndClear();
+ }
+ o_rValue <<= sPersistentPath;
+ return;
+ }
+
+ OPropertyStateContainer::getFastPropertyValue( o_rValue, i_nHandle );
+}
+
+Reference< XPropertySetInfo > SAL_CALL ODocumentDefinition::getPropertySetInfo( ) throw(RuntimeException)
+{
+ Reference<XPropertySetInfo> xInfo( createPropertySetInfo( getInfoHelper() ) );
+ return xInfo;
+}
+
+IPropertyArrayHelper& ODocumentDefinition::getInfoHelper()
+{
+ return *getArrayHelper();
+}
+
+IPropertyArrayHelper* ODocumentDefinition::createArrayHelper( ) const
+{
+ // properties maintained by our base class (see registerProperties)
+ Sequence< Property > aProps;
+ describeProperties( aProps );
+
+ // properties not maintained by our base class
+ Sequence< Property > aManualProps( 1 );
+ aManualProps[0].Name = PROPERTY_PERSISTENT_PATH;
+ aManualProps[0].Handle = PROPERTY_ID_PERSISTENT_PATH;
+ aManualProps[0].Type = ::getCppuType( static_cast< const ::rtl::OUString* >( NULL ) );
+ aManualProps[0].Attributes = PropertyAttribute::READONLY;
+
+ return new OPropertyArrayHelper( ::comphelper::concatSequences( aProps, aManualProps ) );
+}
+
+class OExecuteImpl
+{
+ sal_Bool& m_rbSet;
+public:
+ OExecuteImpl(sal_Bool& _rbSet) : m_rbSet(_rbSet){ m_rbSet=sal_True; }
+ ~OExecuteImpl(){ m_rbSet = sal_False; }
+};
+
+namespace
+{
+ bool lcl_extractOpenMode( const Any& _rValue, sal_Int32& _out_rMode )
+ {
+ OpenCommandArgument aOpenCommand;
+ if ( _rValue >>= aOpenCommand )
+ _out_rMode = aOpenCommand.Mode;
+ else
+ {
+ OpenCommandArgument2 aOpenCommand2;
+ if ( _rValue >>= aOpenCommand2 )
+ _out_rMode = aOpenCommand2.Mode;
+ else
+ return false;
+ }
+ return true;
+ }
+}
+
+void ODocumentDefinition::impl_removeFrameFromDesktop_throw( const ::comphelper::ComponentContext& _rContxt, const Reference< XFrame >& _rxFrame )
+{
+ Reference< XFramesSupplier > xDesktop( _rContxt.createComponent( (::rtl::OUString)SERVICE_FRAME_DESKTOP ), UNO_QUERY_THROW );
+ Reference< XFrames > xFrames( xDesktop->getFrames(), UNO_QUERY_THROW );
+ xFrames->remove( _rxFrame );
+}
+
+void ODocumentDefinition::impl_onActivateEmbeddedObject_nothrow( const bool i_bReactivated )
+{
+ try
+ {
+ Reference< XModel > xModel( getComponent(), UNO_QUERY );
+ Reference< XController > xController( xModel.is() ? xModel->getCurrentController() : Reference< XController >() );
+ if ( !xController.is() )
+ return;
+
+ if ( !m_xListener.is() )
+ // it's the first time the embedded object has been activated
+ // create an OEmbedObjectHolder
+ m_xListener = new OEmbedObjectHolder( m_xEmbeddedObject, this );
+
+ // raise the window to top (especially necessary if this is not the first activation)
+ Reference< XFrame > xFrame( xController->getFrame(), UNO_SET_THROW );
+ Reference< XTopWindow > xTopWindow( xFrame->getContainerWindow(), UNO_QUERY_THROW );
+ xTopWindow->toFront();
+
+ // remove the frame from the desktop's frame collection because we need full control of it.
+ impl_removeFrameFromDesktop_throw( m_aContext, xFrame );
+
+ // ensure that we ourself are kept alive as long as the embedded object's frame is
+ // opened
+ LifetimeCoupler::couple( *this, xFrame.get() );
+
+ // init the edit view
+ if ( m_bForm && m_bOpenInDesign && !i_bReactivated )
+ impl_initFormEditView( xController );
+ }
+ catch( const RuntimeException& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+}
+
+namespace
+{
+ // =========================================================================
+ // = PreserveVisualAreaSize
+ // =========================================================================
+ /** stack-guard for preserving the size of the VisArea of an XModel
+ */
+ class PreserveVisualAreaSize
+ {
+ private:
+ Reference< XVisualObject > m_xVisObject;
+ awt::Size m_aOriginalSize;
+
+ public:
+ inline PreserveVisualAreaSize( const Reference< XModel >& _rxModel )
+ :m_xVisObject( _rxModel, UNO_QUERY )
+ {
+ if ( m_xVisObject.is() )
+ {
+ try
+ {
+ m_aOriginalSize = m_xVisObject->getVisualAreaSize( Aspects::MSOLE_CONTENT );
+ }
+ catch ( Exception& )
+ {
+ DBG_ERROR( "PreserveVisualAreaSize::PreserveVisualAreaSize: caught an exception!" );
+ }
+ }
+ }
+
+ inline ~PreserveVisualAreaSize()
+ {
+ if ( m_xVisObject.is() && m_aOriginalSize.Width && m_aOriginalSize.Height )
+ {
+ try
+ {
+ m_xVisObject->setVisualAreaSize( Aspects::MSOLE_CONTENT, m_aOriginalSize );
+ }
+ catch ( Exception& )
+ {
+ DBG_ERROR( "PreserveVisualAreaSize::~PreserveVisualAreaSize: caught an exception!" );
+ }
+ }
+ }
+ };
+
+ // =========================================================================
+ // = LayoutManagerLock
+ // =========================================================================
+ /** helper class for stack-usage which during its lifetime locks a layout manager
+ */
+ class LayoutManagerLock
+ {
+ private:
+ Reference< XLayoutManager > m_xLayoutManager;
+
+ public:
+ inline LayoutManagerLock( const Reference< XController >& _rxController )
+ {
+ DBG_ASSERT( _rxController.is(), "LayoutManagerLock::LayoutManagerLock: this will crash!" );
+ Reference< XFrame > xFrame( _rxController->getFrame() );
+ try
+ {
+ Reference< XPropertySet > xPropSet( xFrame, UNO_QUERY_THROW );
+ m_xLayoutManager.set(
+ xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ) ) ),
+ UNO_QUERY_THROW );
+ m_xLayoutManager->lock();
+
+ }
+ catch( Exception& )
+ {
+ DBG_ERROR( "LayoutManagerLock::LayoutManagerLock: caught an exception!" );
+ }
+ }
+
+ inline ~LayoutManagerLock()
+ {
+ try
+ {
+ // unlock the layout manager
+ if ( m_xLayoutManager.is() )
+ m_xLayoutManager->unlock();
+ }
+ catch( Exception& )
+ {
+ DBG_ERROR( "LayoutManagerLock::~LayoutManagerLock: caught an exception!" );
+ }
+ }
+ };
+}
+
+void ODocumentDefinition::impl_initFormEditView( const Reference< XController >& _rxController )
+{
+ try
+ {
+ Reference< XViewSettingsSupplier > xSettingsSupplier( _rxController, UNO_QUERY_THROW );
+ Reference< XPropertySet > xViewSettings( xSettingsSupplier->getViewSettings(), UNO_QUERY_THROW );
+
+ // the below code could indirectly tamper with the "modified" flag of the model, temporarily disable this
+ LockModifiable aLockModify( _rxController->getModel() );
+
+ // The visual area size can be changed by the setting of the following properties
+ // so it should be restored later
+ PreserveVisualAreaSize aPreserveVisAreaSize( _rxController->getModel() );
+
+ // Layout manager should not layout while the size is still not restored
+ // so it will stay locked for this time
+ LayoutManagerLock aLockLayout( _rxController );
+
+ // setting of the visual properties
+ xViewSettings->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowRulers")),makeAny(sal_True));
+ xViewSettings->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowVertRuler")),makeAny(sal_True));
+ xViewSettings->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowHoriRuler")),makeAny(sal_True));
+ xViewSettings->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IsRasterVisible")),makeAny(sal_True));
+ xViewSettings->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IsSnapToRaster")),makeAny(sal_True));
+ xViewSettings->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowOnlineLayout")),makeAny(sal_True));
+ xViewSettings->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("RasterSubdivisionX")),makeAny(sal_Int32(5)));
+ xViewSettings->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("RasterSubdivisionY")),makeAny(sal_Int32(5)));
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+}
+
+void ODocumentDefinition::impl_showOrHideComponent_throw( const bool i_bShow )
+{
+ const sal_Int32 nCurrentState = m_xEmbeddedObject.is() ? m_xEmbeddedObject->getCurrentState() : EmbedStates::LOADED;
+ switch ( nCurrentState )
+ {
+ default:
+ case EmbedStates::LOADED:
+ throw embed::WrongStateException( ::rtl::OUString(), *this );
+
+ case EmbedStates::RUNNING:
+ if ( !i_bShow )
+ // fine, a running (and not yet active) object is never visible
+ return;
+ {
+ LockModifiable aLockModify( impl_getComponent_throw() );
+ m_xEmbeddedObject->changeState( EmbedStates::ACTIVE );
+ impl_onActivateEmbeddedObject_nothrow( false );
+ }
+ break;
+
+ case EmbedStates::ACTIVE:
+ {
+ Reference< XModel > xEmbeddedDoc( impl_getComponent_throw( true ), UNO_QUERY_THROW );
+ Reference< XController > xEmbeddedController( xEmbeddedDoc->getCurrentController(), UNO_SET_THROW );
+ Reference< XFrame > xEmbeddedFrame( xEmbeddedController->getFrame(), UNO_SET_THROW );
+ Reference< XWindow > xEmbeddedWindow( xEmbeddedFrame->getContainerWindow(), UNO_SET_THROW );
+ xEmbeddedWindow->setVisible( i_bShow );
+ }
+ break;
+ }
+}
+
+Any ODocumentDefinition::onCommandOpenSomething( const Any& _rOpenArgument, const bool _bActivate,
+ const Reference< XCommandEnvironment >& _rxEnvironment )
+{
+ OExecuteImpl aExecuteGuard( m_bInExecute );
+
+ Reference< XConnection > xConnection;
+ sal_Int32 nOpenMode = OpenMode::DOCUMENT;
+
+ ::comphelper::NamedValueCollection aDocumentArgs;
+
+ // for the document, default to the interaction handler as used for loading the DB doc
+ // This might be overwritten below, when examining _rOpenArgument.
+ const ::comphelper::NamedValueCollection& aDBDocArgs( m_pImpl->m_pDataSource->getMediaDescriptor() );
+ Reference< XInteractionHandler > xHandler( aDBDocArgs.getOrDefault( "InteractionHandler", Reference< XInteractionHandler >() ) );
+ if ( xHandler.is() )
+ aDocumentArgs.put( "InteractionHandler", xHandler );
+
+ ::boost::optional< sal_Int16 > aDocumentMacroMode;
+
+ if ( !lcl_extractOpenMode( _rOpenArgument, nOpenMode ) )
+ {
+ Sequence< PropertyValue > aArguments;
+ if ( _rOpenArgument >>= aArguments )
+ {
+ const PropertyValue* pIter = aArguments.getConstArray();
+ const PropertyValue* pEnd = pIter + aArguments.getLength();
+ for ( ;pIter != pEnd; ++pIter )
+ {
+ if ( pIter->Name == PROPERTY_ACTIVE_CONNECTION )
+ {
+ xConnection.set( pIter->Value, UNO_QUERY );
+ continue;
+ }
+
+ if ( lcl_extractOpenMode( pIter->Value, nOpenMode ) )
+ continue;
+
+ if ( pIter->Name.equalsAscii( "MacroExecutionMode" ) )
+ {
+ sal_Int16 nMacroExecMode( !aDocumentMacroMode ? MacroExecMode::USE_CONFIG : *aDocumentMacroMode );
+ OSL_VERIFY( pIter->Value >>= nMacroExecMode );
+ aDocumentMacroMode.reset( nMacroExecMode );
+ continue;
+ }
+
+ // unknown argument -> pass to the loaded document
+ aDocumentArgs.put( pIter->Name, pIter->Value );
+ }
+ }
+ }
+
+ bool bExecuteDBDocMacros = m_pImpl->m_pDataSource->checkMacrosOnLoading();
+ // Note that this call implies the user might be asked for the macro execution mode.
+ // Normally, this would happen when the database document is loaded, and subsequent calls
+ // will simply use the user's decision from this point in time.
+ // However, it is possible to programmatically load forms/reports, without actually
+ // loading the database document into a frame. In this case, the user will be asked
+ // here and now.
+ // #i87741# / 2008-05-05 / frank.schoenheit@sun.com
+
+ // allow the command arguments to downgrade the macro execution mode, but not to upgrade
+ // it
+ if ( ( m_pImpl->m_pDataSource->getImposedMacroExecMode() == MacroExecMode::USE_CONFIG )
+ && bExecuteDBDocMacros
+ )
+ {
+ // while loading the whole database document, USE_CONFIG, was passed.
+ // Additionally, *by now* executing macros from the DB doc is allowed (this is what bExecuteDBDocMacros
+ // indicates). This means either one of:
+ // 1. The DB doc or one of the sub docs contained macros and
+ // 1a. the user explicitly allowed executing them
+ // 1b. the configuration allows executing them without asking the user
+ // 2. Neither the DB doc nor the sub docs contained macros, thus macro
+ // execution was silently enabled, assuming that any macro will be a
+ // user-created macro
+ //
+ // The problem with this: If the to-be-opened sub document has macros embedded in
+ // the content.xml (which is valid ODF, but normally not produced by OOo itself),
+ // then this has not been detected while loading the database document - it would
+ // be too expensive, as it effectively would require loading all forms/reports.
+ //
+ // So, in such a case, and with 2. above, we would silently execute those macros,
+ // regardless of the global security settings - which would be a security issue, of
+ // course.
+ if ( m_pImpl->m_pDataSource->determineEmbeddedMacros() == ODatabaseModelImpl::eNoMacros )
+ {
+ // this is case 2. from above
+ // So, pass a USE_CONFIG to the to-be-loaded document. This means that
+ // the user will be prompted with a security message upon opening this
+ // sub document, in case the settings require this, *and* the document
+ // contains scripts in the content.xml. But this is better than the security
+ // issue we had before ...
+ aDocumentMacroMode.reset( MacroExecMode::USE_CONFIG );
+ }
+ }
+
+ if ( !aDocumentMacroMode )
+ {
+ // nobody so far felt responsible for setting it
+ // => use the DBDoc-wide macro exec mode for the document, too
+ aDocumentMacroMode.reset( bExecuteDBDocMacros ? MacroExecMode::ALWAYS_EXECUTE_NO_WARN : MacroExecMode::NEVER_EXECUTE );
+ }
+ aDocumentArgs.put( "MacroExecutionMode", *aDocumentMacroMode );
+
+ if ( ( nOpenMode == OpenMode::ALL )
+ || ( nOpenMode == OpenMode::FOLDERS )
+ || ( nOpenMode == OpenMode::DOCUMENTS )
+ || ( nOpenMode == OpenMode::DOCUMENT_SHARE_DENY_NONE )
+ || ( nOpenMode == OpenMode::DOCUMENT_SHARE_DENY_WRITE )
+ )
+ {
+ // not supported
+ ucbhelper::cancelCommandExecution(
+ makeAny( UnsupportedOpenModeException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ sal_Int16( nOpenMode ) ) ),
+ _rxEnvironment );
+ // Unreachable
+ DBG_ERROR( "unreachable" );
+ }
+
+ OSL_ENSURE( m_pImpl->m_aProps.sPersistentName.getLength(),
+ "ODocumentDefinition::onCommandOpenSomething: no persistent name - cannot load!" );
+ if ( !m_pImpl->m_aProps.sPersistentName.getLength() )
+ return Any();
+
+ // embedded objects themself do not support the hidden flag. We implement support for
+ // it by changing the STATE to RUNNING only, instead of ACTIVE.
+ bool bOpenHidden = aDocumentArgs.getOrDefault( "Hidden", false );
+ aDocumentArgs.remove( "Hidden" );
+
+ loadEmbeddedObject( xConnection, Sequence< sal_Int8 >(), aDocumentArgs.getPropertyValues(), false, !m_bOpenInDesign );
+ OSL_ENSURE( m_xEmbeddedObject.is(), "ODocumentDefinition::onCommandOpenSomething: what's this?" );
+ if ( !m_xEmbeddedObject.is() )
+ return Any();
+
+ Reference< XModel > xModel( getComponent(), UNO_QUERY );
+ Reference< report::XReportDefinition > xReportDefinition(xModel,UNO_QUERY);
+
+ Reference< XModule > xModule( xModel, UNO_QUERY );
+ if ( xModule.is() )
+ {
+ if ( m_bForm )
+ xModule->setIdentifier( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.FormDesign" ) ) );
+ else if ( !xReportDefinition.is() )
+ xModule->setIdentifier( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.TextReportDesign" ) ) );
+
+ updateDocumentTitle();
+ }
+
+ bool bIsAliveNewStyleReport = ( !m_bOpenInDesign && xReportDefinition.is() );
+ if ( bIsAliveNewStyleReport )
+ {
+ // we are in ReadOnly mode
+ // we would like to open the Writer or Calc with the report direct, without design it.
+ Reference< report::XReportEngine > xReportEngine( m_aContext.createComponent( "com.sun.star.comp.report.OReportEngineJFree" ), UNO_QUERY_THROW );
+
+ xReportEngine->setReportDefinition(xReportDefinition);
+ xReportEngine->setActiveConnection(m_xLastKnownConnection);
+ if ( bOpenHidden )
+ return makeAny( xReportEngine->createDocumentModel() );
+ return makeAny( xReportEngine->createDocumentAlive( NULL ) );
+ }
+
+ if ( _bActivate && !bOpenHidden )
+ {
+ LockModifiable aLockModify( impl_getComponent_throw() );
+ m_xEmbeddedObject->changeState( EmbedStates::ACTIVE );
+ impl_onActivateEmbeddedObject_nothrow( false );
+ }
+ else
+ {
+ // ensure that we ourself are kept alive as long as the document is open
+ LifetimeCoupler::couple( *this, xModel.get() );
+ }
+
+ if ( !m_bForm && m_pImpl->m_aProps.bAsTemplate && !m_bOpenInDesign )
+ ODocumentDefinition::fillReportData( m_aContext, getComponent(), xConnection );
+
+ return makeAny( xModel );
+}
+
+Any SAL_CALL ODocumentDefinition::execute( const Command& aCommand, sal_Int32 CommandId, const Reference< XCommandEnvironment >& Environment ) throw (Exception, CommandAbortedException, RuntimeException)
+{
+ Any aRet;
+
+ sal_Bool bOpen = aCommand.Name.equalsAscii( "open" );
+ sal_Bool bOpenInDesign = aCommand.Name.equalsAscii( "openDesign" );
+ sal_Bool bOpenForMail = aCommand.Name.equalsAscii( "openForMail" );
+ if ( bOpen || bOpenInDesign || bOpenForMail )
+ {
+ // opening the document involves a lot of VCL code, which is not thread-safe, but needs the SolarMutex locked.
+ // Unfortunately, the DocumentDefinition, as well as the EmbeddedObject implementation, calls into VCL-dependent
+ // components *without* releasing the own mutex, which is a guaranteed recipe for deadlocks.
+ // We have control over this implementation here, and in modifying it to release the own mutex before calling into
+ // the VCL-dependent components is not too difficult (was there, seen it).
+ // However, we do /not/ have control over the EmbeddedObject implementation, and from a first look, it seems as
+ // making it release the own mutex before calling SolarMutex-code is ... difficult, at least.
+ // So, to be on the same side, we lock the SolarMutex here. Yes, it sucks.
+ ::SolarMutexGuard aSolarGuard;
+ ::osl::ClearableMutexGuard aGuard(m_aMutex);
+ if ( m_bInExecute )
+ return aRet;
+
+ bool bActivateObject = true;
+ if ( bOpenForMail )
+ {
+ OSL_ENSURE( false, "ODocumentDefinition::execute: 'openForMail' should not be used anymore - use the 'Hidden' parameter instead!" );
+ bActivateObject = false;
+ }
+
+ // if the object is already opened, do nothing
+ if ( m_xEmbeddedObject.is() )
+ {
+ sal_Int32 nCurrentState = m_xEmbeddedObject->getCurrentState();
+ bool bIsActive = ( nCurrentState == EmbedStates::ACTIVE );
+
+ if ( bIsActive )
+ {
+ // exception: new-style reports always create a new document when "open" is executed
+ Reference< report::XReportDefinition > xReportDefinition( impl_getComponent_throw( false ), UNO_QUERY );
+ bool bIsAliveNewStyleReport = ( xReportDefinition.is() && ( bOpen || bOpenForMail ) );
+
+ if ( !bIsAliveNewStyleReport )
+ {
+ impl_onActivateEmbeddedObject_nothrow( true );
+ return makeAny( getComponent() );
+ }
+ }
+ }
+
+ m_bOpenInDesign = bOpenInDesign || bOpenForMail;
+ return onCommandOpenSomething( aCommand.Argument, bActivateObject, Environment );
+ }
+
+ ::osl::ClearableMutexGuard aGuard(m_aMutex);
+ if ( m_bInExecute )
+ return aRet;
+
+ if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "copyTo" ) ) )
+ {
+ Sequence<Any> aIni;
+ aCommand.Argument >>= aIni;
+ if ( aIni.getLength() != 2 )
+ {
+ OSL_ENSURE( sal_False, "Wrong argument type!" );
+ ucbhelper::cancelCommandExecution(
+ makeAny( IllegalArgumentException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+ Reference< XStorage> xDest(aIni[0],UNO_QUERY);
+ ::rtl::OUString sPersistentName;
+ aIni[1] >>= sPersistentName;
+ Reference< XStorage> xStorage = getContainerStorage();
+
+ xStorage->copyElementTo(m_pImpl->m_aProps.sPersistentName,xDest,sPersistentName);
+ }
+ else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "preview" ) ) )
+ {
+ onCommandPreview(aRet);
+ }
+ else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "insert" ) ) )
+ {
+ Sequence<Any> aIni;
+ aCommand.Argument >>= aIni;
+ if ( !aIni.getLength() )
+ {
+ OSL_ENSURE( sal_False, "Wrong argument count!" );
+ ucbhelper::cancelCommandExecution(
+ makeAny( IllegalArgumentException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+ ::rtl::OUString sURL;
+ aIni[0] >>= sURL;
+ onCommandInsert( sURL, Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "getdocumentinfo" ) ) // compatibility
+ || aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "getDocumentInfo" ) )
+ )
+ {
+ onCommandGetDocumentProperties( aRet );
+ }
+ else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "delete" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // delete
+ //////////////////////////////////////////////////////////////////
+ closeObject();
+ Reference< XStorage> xStorage = getContainerStorage();
+ if ( xStorage.is() )
+ xStorage->removeElement(m_pImpl->m_aProps.sPersistentName);
+
+ dispose();
+
+ }
+ else if ( ( aCommand.Name.compareToAscii( "storeOwn" ) == 0 ) // compatibility
+ || ( aCommand.Name.compareToAscii( "store" ) == 0 )
+ )
+ {
+ impl_store_throw();
+ }
+ else if ( ( aCommand.Name.compareToAscii( "shutdown" ) == 0 ) // compatibility
+ || ( aCommand.Name.compareToAscii( "close" ) == 0 )
+ )
+ {
+ aRet <<= impl_close_throw();
+ }
+ else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "show" ) ) )
+ {
+ impl_showOrHideComponent_throw( true );
+ }
+ else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "hide" ) ) )
+ {
+ impl_showOrHideComponent_throw( false );
+ }
+ else
+ {
+ aRet = OContentHelper::execute(aCommand,CommandId,Environment);
+ }
+
+ return aRet;
+}
+
+namespace
+{
+ void lcl_resetChildFormsToEmptyDataSource( const Reference< XIndexAccess>& _rxFormsContainer )
+ {
+ OSL_PRECOND( _rxFormsContainer.is(), "lcl_resetChildFormsToEmptyDataSource: illegal call!" );
+ sal_Int32 count = _rxFormsContainer->getCount();
+ for ( sal_Int32 i = 0; i < count; ++i )
+ {
+ Reference< XForm > xForm( _rxFormsContainer->getByIndex( i ), UNO_QUERY );
+ if ( !xForm.is() )
+ continue;
+
+ // if the element is a form, reset its DataSourceName property to an empty string
+ try
+ {
+ Reference< XPropertySet > xFormProps( xForm, UNO_QUERY_THROW );
+ xFormProps->setPropertyValue( PROPERTY_DATASOURCENAME, makeAny( ::rtl::OUString() ) );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ // if the element is a container itself, step down the component hierarchy
+ Reference< XIndexAccess > xContainer( xForm, UNO_QUERY );
+ if ( xContainer.is() )
+ lcl_resetChildFormsToEmptyDataSource( xContainer );
+ }
+ }
+
+ void lcl_resetFormsToEmptyDataSource( const Reference< XEmbeddedObject>& _rxEmbeddedObject )
+ {
+ try
+ {
+ Reference< XComponentSupplier > xCompProv( _rxEmbeddedObject, UNO_QUERY_THROW );
+ Reference< XDrawPageSupplier > xSuppPage( xCompProv->getComponent(), UNO_QUERY_THROW );
+ // if this interface does not exist, then either getComponent returned NULL,
+ // or the document is a multi-page document. The latter is allowed, but currently
+ // simply not handled by this code, as it would not normally happen.
+
+ Reference< XFormsSupplier > xSuppForms( xSuppPage->getDrawPage(), UNO_QUERY_THROW );
+ Reference< XIndexAccess > xForms( xSuppForms->getForms(), UNO_QUERY_THROW );
+ lcl_resetChildFormsToEmptyDataSource( xForms );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ }
+}
+
+void ODocumentDefinition::onCommandInsert( const ::rtl::OUString& _sURL, const Reference< XCommandEnvironment >& Environment )
+ throw( Exception )
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+
+ // Check, if all required properties were set.
+ if ( !_sURL.getLength() || m_xEmbeddedObject.is() )
+ {
+ OSL_ENSURE( sal_False, "Content::onCommandInsert - property value missing!" );
+
+ Sequence< rtl::OUString > aProps( 1 );
+ aProps[ 0 ] = PROPERTY_URL;
+ ucbhelper::cancelCommandExecution(
+ makeAny( MissingPropertiesException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ aProps ) ),
+ Environment );
+ // Unreachable
+ }
+
+ if ( !m_xEmbeddedObject.is() )
+ {
+ Reference< XStorage> xStorage = getContainerStorage();
+ if ( xStorage.is() )
+ {
+ Reference< XEmbedObjectCreator> xEmbedFactory( m_aContext.createComponent( "com.sun.star.embed.EmbeddedObjectCreator" ), UNO_QUERY );
+ if ( xEmbedFactory.is() )
+ {
+ Sequence<PropertyValue> aEmpty,aMediaDesc(1);
+ aMediaDesc[0].Name = PROPERTY_URL;
+ aMediaDesc[0].Value <<= _sURL;
+ m_xEmbeddedObject.set(xEmbedFactory->createInstanceInitFromMediaDescriptor( xStorage
+ ,m_pImpl->m_aProps.sPersistentName
+ ,aMediaDesc
+ ,aEmpty),UNO_QUERY);
+
+ lcl_resetFormsToEmptyDataSource( m_xEmbeddedObject );
+ // #i57669# / 2005-12-01 / frank.schoenheit@sun.com
+
+ Reference<XEmbedPersist> xPersist(m_xEmbeddedObject,UNO_QUERY);
+ if ( xPersist.is() )
+ {
+ xPersist->storeOwn();
+ }
+ try
+ {
+ Reference< com::sun::star::util::XCloseable> xCloseable(m_xEmbeddedObject,UNO_QUERY);
+ if ( xCloseable.is() )
+ xCloseable->close(sal_True);
+ }
+ catch(Exception)
+ {
+ }
+ m_xEmbeddedObject = NULL;
+ }
+ }
+ }
+
+ aGuard.clear();
+}
+
+sal_Bool ODocumentDefinition::save(sal_Bool _bApprove)
+{
+ // default handling: instantiate an interaction handler and let it handle the parameter request
+ if ( !m_bOpenInDesign )
+ return sal_False;
+ try
+ {
+
+ {
+ ::SolarMutexGuard aSolarGuard;
+
+ // the request
+ Reference<XNameAccess> xName(m_xParentContainer,UNO_QUERY);
+ DocumentSaveRequest aRequest;
+ aRequest.Name = m_pImpl->m_aProps.aTitle;
+ if ( !aRequest.Name.getLength() )
+ {
+ if ( m_bForm )
+ aRequest.Name = DBACORE_RESSTRING( RID_STR_FORM );
+ else
+ aRequest.Name = DBACORE_RESSTRING( RID_STR_REPORT );
+ aRequest.Name = ::dbtools::createUniqueName(xName,aRequest.Name);
+ }
+
+ aRequest.Content.set(m_xParentContainer,UNO_QUERY);
+ OInteractionRequest* pRequest = new OInteractionRequest(makeAny(aRequest));
+ Reference< XInteractionRequest > xRequest(pRequest);
+ // some knittings
+ // two continuations allowed: OK and Cancel
+ ODocumentSaveContinuation* pDocuSave = NULL;
+
+ if ( !m_pImpl->m_aProps.aTitle.getLength() )
+ {
+ pDocuSave = new ODocumentSaveContinuation;
+ pRequest->addContinuation(pDocuSave);
+ }
+ OInteraction< XInteractionApprove >* pApprove = NULL;
+ if ( _bApprove )
+ {
+ pApprove = new OInteraction< XInteractionApprove >;
+ pRequest->addContinuation(pApprove);
+ }
+
+ OInteraction< XInteractionDisapprove >* pDisApprove = new OInteraction< XInteractionDisapprove >;
+ pRequest->addContinuation(pDisApprove);
+
+ OInteractionAbort* pAbort = new OInteractionAbort;
+ pRequest->addContinuation(pAbort);
+
+ // create the handler, let it handle the request
+ Reference< XInteractionHandler > xHandler( m_aContext.createComponent( (::rtl::OUString)SERVICE_TASK_INTERACTION_HANDLER ), UNO_QUERY );
+ if ( xHandler.is() )
+ xHandler->handle(xRequest);
+
+ if ( pAbort->wasSelected() )
+ return sal_False;
+ if ( pDisApprove->wasSelected() )
+ return sal_True;
+ if ( pDocuSave && pDocuSave->wasSelected() )
+ {
+ Reference<XNameContainer> xNC( pDocuSave->getContent(), UNO_QUERY_THROW );
+
+ ::osl::ResettableMutexGuard aGuard( m_aMutex );
+ NameChangeNotifier aNameChangeAndNotify( *this, pDocuSave->getName(), aGuard );
+ m_pImpl->m_aProps.aTitle = pDocuSave->getName();
+
+ Reference< XContent> xContent = this;
+ xNC->insertByName(pDocuSave->getName(),makeAny(xContent));
+
+ updateDocumentTitle();
+ }
+ }
+
+ ::osl::MutexGuard aGuard(m_aMutex);
+ Reference<XEmbedPersist> xPersist(m_xEmbeddedObject,UNO_QUERY);
+ if ( xPersist.is() )
+ {
+ xPersist->storeOwn();
+ notifyDataSourceModified();
+ }
+ }
+ catch(Exception&)
+ {
+ OSL_ENSURE(0,"ODocumentDefinition::save: caught an Exception (tried to let the InteractionHandler handle it)!");
+ }
+ return sal_True;
+}
+
+sal_Bool ODocumentDefinition::saveAs()
+{
+ // default handling: instantiate an interaction handler and let it handle the parameter request
+ if ( !m_bOpenInDesign )
+ return sal_False;
+
+ {
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+ if ( !m_pImpl->m_aProps.aTitle.getLength() )
+ {
+ aGuard.clear();
+ return save(sal_False); // (sal_False) : we don't want an approve dialog
+ }
+ }
+ try
+ {
+ {
+ ::SolarMutexGuard aSolarGuard;
+
+ // the request
+ Reference<XNameAccess> xName(m_xParentContainer,UNO_QUERY);
+ DocumentSaveRequest aRequest;
+ aRequest.Name = m_pImpl->m_aProps.aTitle;
+
+ aRequest.Content.set(m_xParentContainer,UNO_QUERY);
+ OInteractionRequest* pRequest = new OInteractionRequest(makeAny(aRequest));
+ Reference< XInteractionRequest > xRequest(pRequest);
+ // some knittings
+ // two continuations allowed: OK and Cancel
+ ODocumentSaveContinuation* pDocuSave = new ODocumentSaveContinuation;
+ pRequest->addContinuation(pDocuSave);
+ OInteraction< XInteractionDisapprove >* pDisApprove = new OInteraction< XInteractionDisapprove >;
+ pRequest->addContinuation(pDisApprove);
+ OInteractionAbort* pAbort = new OInteractionAbort;
+ pRequest->addContinuation(pAbort);
+
+ // create the handler, let it handle the request
+ Reference< XInteractionHandler > xHandler(m_aContext.createComponent(::rtl::OUString(SERVICE_TASK_INTERACTION_HANDLER)), UNO_QUERY);
+ if ( xHandler.is() )
+ xHandler->handle(xRequest);
+
+ if ( pAbort->wasSelected() )
+ return sal_False;
+ if ( pDisApprove->wasSelected() )
+ return sal_True;
+ if ( pDocuSave->wasSelected() )
+ {
+ ::osl::MutexGuard aGuard(m_aMutex);
+ Reference<XNameContainer> xNC(pDocuSave->getContent(),UNO_QUERY);
+ if ( xNC.is() )
+ {
+ if ( m_pImpl->m_aProps.aTitle != pDocuSave->getName() )
+ {
+ try
+ {
+ Reference< XStorage> xStorage = getContainerStorage();
+ const static ::rtl::OUString sBaseName(RTL_CONSTASCII_USTRINGPARAM("Obj"));
+
+ Reference<XNameAccess> xElements(xStorage,UNO_QUERY_THROW);
+ ::rtl::OUString sPersistentName = ::dbtools::createUniqueName(xElements,sBaseName);
+ xStorage->copyElementTo(m_pImpl->m_aProps.sPersistentName,xStorage,sPersistentName);
+
+ ::rtl::OUString sOldName = m_pImpl->m_aProps.aTitle;
+ rename(pDocuSave->getName());
+ updateDocumentTitle();
+
+ Sequence< Any > aArguments(3);
+ PropertyValue aValue;
+ // set as folder
+ aValue.Name = PROPERTY_NAME;
+ aValue.Value <<= sOldName;
+ aArguments[0] <<= aValue;
+
+ aValue.Name = PROPERTY_PERSISTENT_NAME;
+ aValue.Value <<= sPersistentName;
+ aArguments[1] <<= aValue;
+
+ aValue.Name = PROPERTY_AS_TEMPLATE;
+ aValue.Value <<= m_pImpl->m_aProps.bAsTemplate;
+ aArguments[2] <<= aValue;
+
+ Reference< XMultiServiceFactory > xORB( m_xParentContainer, UNO_QUERY_THROW );
+ Reference< XInterface > xComponent( xORB->createInstanceWithArguments( SERVICE_SDB_DOCUMENTDEFINITION, aArguments ) );
+ Reference< XNameContainer > xNameContainer( m_xParentContainer, UNO_QUERY_THROW );
+ xNameContainer->insertByName( sOldName, makeAny( xComponent ) );
+ }
+ catch(Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+ Reference<XEmbedPersist> xPersist(m_xEmbeddedObject,UNO_QUERY);
+ if ( xPersist.is() )
+ {
+ xPersist->storeOwn();
+ notifyDataSourceModified();
+ }
+ }
+ }
+ }
+
+ }
+ catch(Exception&)
+ {
+ OSL_ENSURE(0,"ODocumentDefinition::save: caught an Exception (tried to let the InteractionHandler handle it)!");
+ }
+ return sal_True;
+}
+
+namespace
+{
+ // .........................................................................
+ void lcl_putLoadArgs( ::comphelper::NamedValueCollection& _io_rArgs, const optional_bool _bSuppressMacros, const optional_bool _bReadOnly )
+ {
+ if ( !!_bSuppressMacros )
+ {
+ if ( *_bSuppressMacros )
+ {
+ // if we're to suppress macros, do exactly this
+ _io_rArgs.put( "MacroExecutionMode", MacroExecMode::NEVER_EXECUTE );
+ }
+ else
+ {
+ // otherwise, put the setting only if not already present
+ if ( !_io_rArgs.has( "MacroExecutionMode" ) )
+ {
+ _io_rArgs.put( "MacroExecutionMode", MacroExecMode::USE_CONFIG );
+ }
+ }
+ }
+
+ if ( !!_bReadOnly )
+ _io_rArgs.put( "ReadOnly", *_bReadOnly );
+ }
+}
+
+namespace
+{
+ Reference< XFrame > lcl_getDatabaseDocumentFrame( ODatabaseModelImpl& _rImpl )
+ {
+ Reference< XModel > xDatabaseDocumentModel( _rImpl.getModel_noCreate() );
+
+ Reference< XController > xDatabaseDocumentController;
+ if ( xDatabaseDocumentModel.is() )
+ xDatabaseDocumentController = xDatabaseDocumentModel->getCurrentController();
+
+ Reference< XFrame > xFrame;
+ if ( xDatabaseDocumentController.is() )
+ xFrame = xDatabaseDocumentController->getFrame();
+
+ return xFrame;
+ }
+}
+
+sal_Bool ODocumentDefinition::objectSupportsEmbeddedScripts() const
+{
+ bool bAllowDocumentMacros = !m_pImpl->m_pDataSource
+ || ( m_pImpl->m_pDataSource->determineEmbeddedMacros() == ODatabaseModelImpl::eSubDocumentMacros );
+
+ // if *any* of the objects of the database document already has macros, we continue to allow it
+ // to have them, until the user did a migration.
+ // If there are no macros, yet, we don't allow to create them
+
+ return bAllowDocumentMacros;
+}
+
+::rtl::OUString ODocumentDefinition::determineContentType() const
+{
+ return lcl_determineContentType_nothrow( getContainerStorage(), m_pImpl->m_aProps.sPersistentName );
+}
+
+void ODocumentDefinition::separateOpenCommandArguments( const Sequence< PropertyValue >& i_rOpenCommandArguments,
+ ::comphelper::NamedValueCollection& o_rDocumentLoadArgs, ::comphelper::NamedValueCollection& o_rEmbeddedObjectDescriptor )
+{
+ ::comphelper::NamedValueCollection aOpenCommandArguments( i_rOpenCommandArguments );
+
+ const sal_Char* pObjectDescriptorArgs[] =
+ {
+ "RecoveryStorage"
+ };
+ for ( size_t i=0; i < SAL_N_ELEMENTS( pObjectDescriptorArgs ); ++i )
+ {
+ if ( aOpenCommandArguments.has( pObjectDescriptorArgs[i] ) )
+ {
+ o_rEmbeddedObjectDescriptor.put( pObjectDescriptorArgs[i], aOpenCommandArguments.get( pObjectDescriptorArgs[i] ) );
+ aOpenCommandArguments.remove( pObjectDescriptorArgs[i] );
+ }
+ }
+
+ o_rDocumentLoadArgs.merge( aOpenCommandArguments, false );
+}
+
+Sequence< PropertyValue > ODocumentDefinition::fillLoadArgs( const Reference< XConnection>& _xConnection, const bool _bSuppressMacros, const bool _bReadOnly,
+ const Sequence< PropertyValue >& i_rOpenCommandArguments, Sequence< PropertyValue >& _out_rEmbeddedObjectDescriptor )
+{
+ // .........................................................................
+ // (re-)create interceptor, and put it into the descriptor of the embedded object
+ if ( m_pInterceptor )
+ {
+ m_pInterceptor->dispose();
+ m_pInterceptor->release();
+ m_pInterceptor = NULL;
+ }
+
+ m_pInterceptor = new OInterceptor( this ,_bReadOnly);
+ m_pInterceptor->acquire();
+ Reference<XDispatchProviderInterceptor> xInterceptor = m_pInterceptor;
+
+ ::comphelper::NamedValueCollection aEmbeddedDescriptor;
+ aEmbeddedDescriptor.put( "OutplaceDispatchInterceptor", xInterceptor );
+
+ // .........................................................................
+ ::comphelper::NamedValueCollection aMediaDesc;
+ separateOpenCommandArguments( i_rOpenCommandArguments, aMediaDesc, aEmbeddedDescriptor );
+
+ // .........................................................................
+ // create the OutplaceFrameProperties, and put them into the descriptor of the embedded object
+ ::comphelper::NamedValueCollection OutplaceFrameProperties;
+ OutplaceFrameProperties.put( "TopWindow", (sal_Bool)sal_True );
+
+ Reference< XFrame > xParentFrame;
+ if ( m_pImpl->m_pDataSource )
+ xParentFrame = lcl_getDatabaseDocumentFrame( *m_pImpl->m_pDataSource );
+ if ( !xParentFrame.is() )
+ { // i87957 we need a parent frame
+ Reference< XComponentLoader > xDesktop( m_aContext.createComponent( (::rtl::OUString)SERVICE_FRAME_DESKTOP ), UNO_QUERY_THROW );
+ xParentFrame.set( xDesktop, UNO_QUERY );
+ if ( xParentFrame.is() )
+ {
+ Reference<util::XCloseable> xCloseable(m_pImpl->m_pDataSource->getModel_noCreate(),UNO_QUERY);
+ if ( xCloseable.is() )
+ {
+ xCloseable->addCloseListener(this);
+ m_bRemoveListener = sal_True;
+ }
+ }
+ }
+ OSL_ENSURE( xParentFrame.is(), "ODocumentDefinition::fillLoadArgs: no parent frame!" );
+ if ( xParentFrame.is() )
+ OutplaceFrameProperties.put( "ParentFrame", xParentFrame );
+
+ aEmbeddedDescriptor.put( "OutplaceFrameProperties", OutplaceFrameProperties.getNamedValues() );
+
+ // .........................................................................
+ // tell the embedded object to have (or not have) script support
+ aEmbeddedDescriptor.put( "EmbeddedScriptSupport", (sal_Bool)objectSupportsEmbeddedScripts() );
+
+ // .........................................................................
+ // tell the embedded object to not participate in the document recovery game - the DB doc will handle it
+ aEmbeddedDescriptor.put( "DocumentRecoverySupport", (sal_Bool)sal_False );
+
+ // .........................................................................
+ // pass the descriptor of the embedded object to the caller
+ aEmbeddedDescriptor >>= _out_rEmbeddedObjectDescriptor;
+
+ // .........................................................................
+ // create the ComponentData, and put it into the document's media descriptor
+ {
+ ::comphelper::NamedValueCollection aComponentData;
+ aComponentData.put( "ActiveConnection", _xConnection );
+ aComponentData.put( "ApplyFormDesignMode", !_bReadOnly );
+ aMediaDesc.put( "ComponentData", aComponentData.getPropertyValues() );
+ }
+
+ if ( m_pImpl->m_aProps.aTitle.getLength() )
+ aMediaDesc.put( "DocumentTitle", m_pImpl->m_aProps.aTitle );
+
+ aMediaDesc.put( "DocumentBaseURL", m_pImpl->m_pDataSource->getURL() );
+
+ // .........................................................................
+ // put the common load arguments into the document's media descriptor
+ lcl_putLoadArgs( aMediaDesc, optional_bool( _bSuppressMacros ), optional_bool( _bReadOnly ) );
+
+ return aMediaDesc.getPropertyValues();
+}
+
+void ODocumentDefinition::loadEmbeddedObject( const Reference< XConnection >& i_rConnection, const Sequence< sal_Int8 >& _aClassID,
+ const Sequence< PropertyValue >& i_rOpenCommandArguments, const bool _bSuppressMacros, const bool _bReadOnly )
+{
+ if ( !m_xEmbeddedObject.is() )
+ {
+ Reference< XStorage> xStorage = getContainerStorage();
+ if ( xStorage.is() )
+ {
+ Reference< XEmbedObjectFactory> xEmbedFactory( m_aContext.createComponent( "com.sun.star.embed.OOoEmbeddedObjectFactory" ), UNO_QUERY );
+ if ( xEmbedFactory.is() )
+ {
+ ::rtl::OUString sDocumentService;
+ sal_Bool bSetSize = sal_False;
+ sal_Int32 nEntryConnectionMode = EntryInitModes::DEFAULT_INIT;
+ Sequence< sal_Int8 > aClassID = _aClassID;
+ if ( aClassID.getLength() )
+ {
+ nEntryConnectionMode = EntryInitModes::TRUNCATE_INIT;
+ bSetSize = sal_True;
+ }
+ else
+ {
+ sDocumentService = GetDocumentServiceFromMediaType( getContentType(), m_aContext, aClassID );
+ // check if we are not a form and
+ // the com.sun.star.report.pentaho.SOReportJobFactory is not present.
+ if ( !m_bForm && !sDocumentService.equalsAscii("com.sun.star.text.TextDocument"))
+ {
+ // we seem to be a "new style" report, check if report extension is present.
+ Reference< XContentEnumerationAccess > xEnumAccess( m_aContext.getLegacyServiceFactory(), UNO_QUERY );
+ const ::rtl::OUString sReportEngineServiceName = ::dbtools::getDefaultReportEngineServiceName(m_aContext.getLegacyServiceFactory());
+ Reference< XEnumeration > xEnumDrivers = xEnumAccess->createContentEnumeration(sReportEngineServiceName);
+ if ( !xEnumDrivers.is() || !xEnumDrivers->hasMoreElements() )
+ {
+ com::sun::star::io::WrongFormatException aWFE;
+ aWFE.Message = DBACORE_RESSTRING( RID_STR_MISSING_EXTENSION );
+ throw aWFE;
+ }
+ }
+ if ( !aClassID.getLength() )
+ {
+ if ( m_bForm )
+ aClassID = MimeConfigurationHelper::GetSequenceClassID(SO3_SW_CLASSID);
+ else
+ {
+ aClassID = MimeConfigurationHelper::GetSequenceClassID(SO3_RPT_CLASSID_90);
+ }
+ }
+ }
+
+ OSL_ENSURE( aClassID.getLength(),"No Class ID" );
+
+ Sequence< PropertyValue > aEmbeddedObjectDescriptor;
+ Sequence< PropertyValue > aLoadArgs( fillLoadArgs(
+ i_rConnection, _bSuppressMacros, _bReadOnly, i_rOpenCommandArguments, aEmbeddedObjectDescriptor ) );
+
+ m_xEmbeddedObject.set(xEmbedFactory->createInstanceUserInit(aClassID
+ ,sDocumentService
+ ,xStorage
+ ,m_pImpl->m_aProps.sPersistentName
+ ,nEntryConnectionMode
+ ,aLoadArgs
+ ,aEmbeddedObjectDescriptor
+ ),UNO_QUERY);
+ if ( m_xEmbeddedObject.is() )
+ {
+ if ( !m_pClientHelper )
+ {
+ m_pClientHelper = new OEmbeddedClientHelper(this);
+ m_pClientHelper->acquire();
+ }
+ Reference<XEmbeddedClient> xClient = m_pClientHelper;
+ m_xEmbeddedObject->setClientSite(xClient);
+ m_xEmbeddedObject->changeState(EmbedStates::RUNNING);
+ if ( bSetSize )
+ {
+ LockModifiable aLockModify( impl_getComponent_throw( false ) );
+
+ awt::Size aSize( DEFAULT_WIDTH, DEFAULT_HEIGHT );
+ m_xEmbeddedObject->setVisualAreaSize(Aspects::MSOLE_CONTENT,aSize);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ sal_Int32 nCurrentState = m_xEmbeddedObject->getCurrentState();
+ if ( nCurrentState == EmbedStates::LOADED )
+ {
+ if ( !m_pClientHelper )
+ {
+ m_pClientHelper = new OEmbeddedClientHelper(this);
+ m_pClientHelper->acquire();
+ }
+ Reference<XEmbeddedClient> xClient = m_pClientHelper;
+ m_xEmbeddedObject->setClientSite(xClient);
+
+ Sequence< PropertyValue > aEmbeddedObjectDescriptor;
+ Sequence< PropertyValue > aLoadArgs( fillLoadArgs(
+ i_rConnection, _bSuppressMacros, _bReadOnly, i_rOpenCommandArguments, aEmbeddedObjectDescriptor ) );
+
+ Reference<XCommonEmbedPersist> xCommon(m_xEmbeddedObject,UNO_QUERY);
+ OSL_ENSURE(xCommon.is(),"unsupported interface!");
+ if ( xCommon.is() )
+ xCommon->reload( aLoadArgs, aEmbeddedObjectDescriptor );
+ m_xEmbeddedObject->changeState(EmbedStates::RUNNING);
+ }
+ else
+ {
+ OSL_ENSURE( ( nCurrentState == EmbedStates::RUNNING ) || ( nCurrentState == EmbedStates::ACTIVE ),
+ "ODocumentDefinition::loadEmbeddedObject: unexpected state!" );
+
+ // if the document was already loaded (which means the embedded object is in state RUNNING or ACTIVE),
+ // then just re-set some model parameters
+ try
+ {
+ // ensure the media descriptor doesn't contain any values which are intended for the
+ // EmbeddedObjectDescriptor only
+ ::comphelper::NamedValueCollection aEmbeddedObjectDescriptor;
+ ::comphelper::NamedValueCollection aNewMediaDesc;
+ separateOpenCommandArguments( i_rOpenCommandArguments, aNewMediaDesc, aEmbeddedObjectDescriptor );
+
+ // merge the new media descriptor into the existing media descriptor
+ const Reference< XModel > xModel( getComponent(), UNO_QUERY_THROW );
+ const Sequence< PropertyValue > aArgs = xModel->getArgs();
+ ::comphelper::NamedValueCollection aExistentMediaDesc( aArgs );
+ aExistentMediaDesc.merge( aNewMediaDesc, sal_False );
+
+ lcl_putLoadArgs( aExistentMediaDesc, optional_bool(), optional_bool() );
+ // don't put _bSuppressMacros and _bReadOnly here - if the document was already
+ // loaded, we should not tamper with its settings.
+ // #i88977# / 2008-05-05 / frank.schoenheit@sun.com
+ // #i86872# / 2008-03-13 / frank.schoenheit@sun.com
+
+ xModel->attachResource( xModel->getURL(), aExistentMediaDesc.getPropertyValues() );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+ }
+
+ // set the OfficeDatabaseDocument instance as parent of the embedded document
+ // #i40358# / 2005-01-19 / frank.schoenheit@sun.com
+ Reference< XChild > xDepdendDocAsChild( getComponent(), UNO_QUERY );
+ if ( xDepdendDocAsChild.is() )
+ {
+ try
+ {
+ if ( !xDepdendDocAsChild->getParent().is() )
+ { // first encounter
+ xDepdendDocAsChild->setParent( getDataSource( m_xParentContainer ) );
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ if ( i_rConnection.is() )
+ m_xLastKnownConnection = i_rConnection;
+}
+
+void ODocumentDefinition::onCommandPreview(Any& _rImage)
+{
+ loadEmbeddedObjectForPreview();
+ if ( m_xEmbeddedObject.is() )
+ {
+ try
+ {
+ Reference<XTransferable> xTransfer(getComponent(),UNO_QUERY);
+ if ( xTransfer.is() )
+ {
+ DataFlavor aFlavor;
+ aFlavor.MimeType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("image/png"));
+ aFlavor.HumanPresentableName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Portable Network Graphics"));
+ aFlavor.DataType = ::getCppuType(static_cast< const Sequence < sal_Int8 >* >(NULL));
+
+ _rImage = xTransfer->getTransferData( aFlavor );
+ }
+ }
+ catch( Exception )
+ {
+ }
+ }
+}
+
+void ODocumentDefinition::getPropertyDefaultByHandle( sal_Int32 /*_nHandle*/, Any& _rDefault ) const
+{
+ _rDefault.clear();
+}
+
+void ODocumentDefinition::onCommandGetDocumentProperties( Any& _rProps )
+{
+ loadEmbeddedObjectForPreview();
+ if ( m_xEmbeddedObject.is() )
+ {
+ try
+ {
+ Reference<XDocumentPropertiesSupplier> xDocSup(
+ getComponent(), UNO_QUERY );
+ if ( xDocSup.is() )
+ _rProps <<= xDocSup->getDocumentProperties();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+}
+
+Reference< util::XCloseable > ODocumentDefinition::impl_getComponent_throw( const bool i_ForceCreate )
+{
+ OSL_ENSURE(m_xEmbeddedObject.is(),"Illegal call for embeddedObject");
+ Reference< util::XCloseable > xComp;
+ if ( m_xEmbeddedObject.is() )
+ {
+ int nState = m_xEmbeddedObject->getCurrentState();
+ if ( ( nState == EmbedStates::LOADED ) && i_ForceCreate )
+ {
+ m_xEmbeddedObject->changeState( EmbedStates::RUNNING );
+ nState = m_xEmbeddedObject->getCurrentState();
+ OSL_ENSURE( nState == EmbedStates::RUNNING, "ODocumentDefinition::impl_getComponent_throw: could not switch to RUNNING!" );
+ }
+
+ if ( nState == EmbedStates::ACTIVE || nState == EmbedStates::RUNNING )
+ {
+ Reference<XComponentSupplier> xCompProv(m_xEmbeddedObject,UNO_QUERY);
+ if ( xCompProv.is() )
+ {
+ xComp = xCompProv->getComponent();
+ OSL_ENSURE(xComp.is(),"No valid component");
+ }
+ }
+ }
+ return xComp;
+}
+
+Reference< util::XCloseable > ODocumentDefinition::getComponent() throw (RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ return impl_getComponent_throw( true );
+}
+
+namespace
+{
+ Reference< XDatabaseDocumentUI > lcl_getDatabaseDocumentUI( ODatabaseModelImpl& _rModelImpl )
+ {
+ Reference< XDatabaseDocumentUI > xUI;
+
+ Reference< XModel > xModel( _rModelImpl.getModel_noCreate() );
+ if ( xModel.is() )
+ xUI.set( xModel->getCurrentController(), UNO_QUERY );
+ return xUI;
+ }
+}
+
+Reference< XComponent > ODocumentDefinition::impl_openUI_nolck_throw( bool _bForEditing )
+{
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+ if ( !m_pImpl || !m_pImpl->m_pDataSource )
+ throw DisposedException();
+
+ Reference< XDatabaseDocumentUI > xUI( lcl_getDatabaseDocumentUI( *m_pImpl->m_pDataSource ) );
+ if ( !xUI.is() )
+ {
+ // no XDatabaseDocumentUI -> just execute the respective command
+ m_bOpenInDesign = _bForEditing;
+ Reference< XComponent > xComponent( onCommandOpenSomething( Any(), true, NULL ), UNO_QUERY );
+ OSL_ENSURE( xComponent.is(), "ODocumentDefinition::impl_openUI_nolck_throw: opening the thingie failed." );
+ return xComponent;
+ }
+
+ Reference< XComponent > xComponent;
+ try
+ {
+ ::rtl::OUString sName( impl_getHierarchicalName( false ) );
+ sal_Int32 nObjectType = m_bForm ? DatabaseObject::FORM : DatabaseObject::REPORT;
+ aGuard.clear();
+
+ xComponent = xUI->loadComponent(
+ nObjectType, sName, _bForEditing
+ );
+ }
+ catch( RuntimeException& ) { throw; }
+ catch( const Exception& )
+ {
+ throw WrappedTargetException(
+ ::rtl::OUString(), *this, ::cppu::getCaughtException() );
+ }
+ return xComponent;
+}
+
+void ODocumentDefinition::impl_store_throw()
+{
+ Reference<XEmbedPersist> xPersist( m_xEmbeddedObject, UNO_QUERY );
+ if ( xPersist.is() )
+ {
+ xPersist->storeOwn();
+ notifyDataSourceModified();
+ }
+}
+
+bool ODocumentDefinition::impl_close_throw()
+{
+ bool bSuccess = prepareClose();
+ if ( bSuccess && m_xEmbeddedObject.is() )
+ {
+ m_xEmbeddedObject->changeState( EmbedStates::LOADED );
+ bSuccess = m_xEmbeddedObject->getCurrentState() == EmbedStates::LOADED;
+ }
+ return bSuccess;
+}
+
+Reference< XComponent > SAL_CALL ODocumentDefinition::open( ) throw (WrappedTargetException, RuntimeException)
+{
+ return impl_openUI_nolck_throw( false );
+}
+
+Reference< XComponent > SAL_CALL ODocumentDefinition::openDesign( ) throw (WrappedTargetException, RuntimeException)
+{
+ return impl_openUI_nolck_throw( true );
+}
+
+void SAL_CALL ODocumentDefinition::store( ) throw (WrappedTargetException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ try
+ {
+ impl_store_throw();
+ }
+ catch( RuntimeException& ) { throw; }
+ catch( const Exception& )
+ {
+ throw WrappedTargetException(
+ ::rtl::OUString(), *this, ::cppu::getCaughtException() );
+ }
+}
+
+::sal_Bool SAL_CALL ODocumentDefinition::close( ) throw (WrappedTargetException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ sal_Bool bSuccess = sal_False;
+ try
+ {
+ bSuccess = impl_close_throw();
+ }
+ catch( RuntimeException& ) { throw; }
+ catch( const Exception& )
+ {
+ throw WrappedTargetException(
+ ::rtl::OUString(), *this, ::cppu::getCaughtException() );
+ }
+ return bSuccess;
+}
+
+::rtl::OUString SAL_CALL ODocumentDefinition::getHierarchicalName() throw (RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ return impl_getHierarchicalName( false );
+}
+
+::rtl::OUString SAL_CALL ODocumentDefinition::composeHierarchicalName( const ::rtl::OUString& i_rRelativeName ) throw (IllegalArgumentException, NoSupportException, RuntimeException)
+{
+ ::rtl::OUStringBuffer aBuffer;
+ aBuffer.append( getHierarchicalName() );
+ aBuffer.append( sal_Unicode( '/' ) );
+ aBuffer.append( i_rRelativeName );
+ return aBuffer.makeStringAndClear();
+}
+
+void SAL_CALL ODocumentDefinition::rename( const ::rtl::OUString& _rNewName ) throw (SQLException, ElementExistException, RuntimeException)
+{
+ try
+ {
+ ::osl::ResettableMutexGuard aGuard(m_aMutex);
+ if ( _rNewName.equals( m_pImpl->m_aProps.aTitle ) )
+ return;
+
+ // document definitions are organized in a hierarchical way, so reject names
+ // which contain a /, as this is reserved for hierarchy level separation
+ if ( _rNewName.indexOf( '/' ) != -1 )
+ m_aErrorHelper.raiseException( ErrorCondition::DB_OBJECT_NAME_WITH_SLASHES, *this );
+
+ NameChangeNotifier aNameChangeAndNotify( *this, _rNewName, aGuard );
+ m_pImpl->m_aProps.aTitle = _rNewName;
+
+ if ( m_xEmbeddedObject.is() && m_xEmbeddedObject->getCurrentState() == EmbedStates::ACTIVE )
+ updateDocumentTitle();
+ }
+ catch(const PropertyVetoException&)
+ {
+ throw ElementExistException(_rNewName,*this);
+ }
+}
+
+Reference< XStorage> ODocumentDefinition::getContainerStorage() const
+{
+ return m_pImpl->m_pDataSource
+ ? m_pImpl->m_pDataSource->getStorage( m_bForm ? ODatabaseModelImpl::E_FORM : ODatabaseModelImpl::E_REPORT )
+ : Reference< XStorage>();
+}
+
+sal_Bool ODocumentDefinition::isModified()
+{
+ osl::ClearableGuard< osl::Mutex > aGuard(m_aMutex);
+ sal_Bool bRet = sal_False;
+ if ( m_xEmbeddedObject.is() )
+ {
+ Reference<XModifiable> xModel(getComponent(),UNO_QUERY);
+ bRet = xModel.is() && xModel->isModified();
+ }
+ return bRet;
+}
+
+bool ODocumentDefinition::prepareClose()
+{
+ if ( !m_xEmbeddedObject.is() )
+ return true;
+
+ try
+ {
+ // suspend the controller. Embedded objects are not allowed to raise
+ // own UI at their own discretion, instead, this has always to be triggered
+ // by the embedding component. Thus, we do the suspend call here.
+ // #i49370# / 2005-06-09 / frank.schoenheit@sun.com
+
+ Reference< util::XCloseable > xComponent( impl_getComponent_throw( false ) );
+ if ( !xComponent.is() )
+ return true;
+
+ Reference< XModel > xModel( xComponent, UNO_QUERY );
+ Reference< XController > xController;
+ if ( xModel.is() )
+ xController = xModel->getCurrentController();
+
+ OSL_ENSURE( xController.is() || ( m_xEmbeddedObject->getCurrentState() < EmbedStates::ACTIVE ),
+ "ODocumentDefinition::prepareClose: no controller!" );
+ if ( !xController.is() )
+ // document has not yet been activated, i.e. has no UI, yet
+ return true;
+
+ sal_Bool bCouldSuspend = xController->suspend( sal_True );
+ if ( !bCouldSuspend )
+ // controller vetoed the closing
+ return false;
+
+ if ( isModified() )
+ {
+ Reference< XFrame > xFrame( xController->getFrame() );
+ if ( xFrame.is() )
+ {
+ Reference< XTopWindow > xTopWindow( xFrame->getContainerWindow(), UNO_QUERY_THROW );
+ xTopWindow->toFront();
+ }
+ if ( !save( sal_True ) )
+ {
+ if ( bCouldSuspend )
+ // revert suspension
+ xController->suspend( sal_False );
+ // saving failed or was cancelled
+ return false;
+ }
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ return true;
+}
+
+void ODocumentDefinition::fillReportData( const ::comphelper::ComponentContext& _rContext,
+ const Reference< util::XCloseable >& _rxComponent,
+ const Reference< XConnection >& _rxActiveConnection )
+{
+ Sequence< Any > aArgs(2);
+ PropertyValue aValue;
+ aValue.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TextDocument" ) );
+ aValue.Value <<= _rxComponent;
+ aArgs[0] <<= aValue;
+ aValue.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ActiveConnection" ) );
+ aValue.Value <<= _rxActiveConnection;
+ aArgs[1] <<= aValue;
+
+ try
+ {
+ Reference< XJobExecutor > xExecuteable(
+ _rContext.createComponentWithArguments( "com.sun.star.wizards.report.CallReportWizard", aArgs ), UNO_QUERY_THROW );
+ xExecuteable->trigger( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "fill" ) ) );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+}
+
+void ODocumentDefinition::updateDocumentTitle()
+{
+ ::rtl::OUString sName = m_pImpl->m_aProps.aTitle;
+ if ( m_pImpl->m_pDataSource )
+ {
+ if ( !sName.getLength() )
+ {
+ if ( m_bForm )
+ sName = DBACORE_RESSTRING( RID_STR_FORM );
+ else
+ sName = DBACORE_RESSTRING( RID_STR_REPORT );
+ Reference< XUntitledNumbers > xUntitledProvider(m_pImpl->m_pDataSource->getModel_noCreate(), UNO_QUERY );
+ if ( xUntitledProvider.is() )
+ sName += ::rtl::OUString::valueOf( xUntitledProvider->leaseNumber(getComponent()) );
+ }
+
+ Reference< XTitle > xDatabaseDocumentModel(m_pImpl->m_pDataSource->getModel_noCreate(),uno::UNO_QUERY);
+ if ( xDatabaseDocumentModel.is() )
+ sName = xDatabaseDocumentModel->getTitle() + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" : ")) + sName;
+ }
+ Reference< XTitle> xTitle(getComponent(),UNO_QUERY);
+ if ( xTitle.is() )
+ xTitle->setTitle(sName);
+}
+
+void SAL_CALL ODocumentDefinition::queryClosing( const lang::EventObject& Source, ::sal_Bool GetsOwnership ) throw (util::CloseVetoException, uno::RuntimeException)
+{
+ (void) Source;
+ (void) GetsOwnership;
+ try
+ {
+ if ( !close() )
+ throw util::CloseVetoException();
+ }
+ catch(const lang::WrappedTargetException&)
+ {
+ throw util::CloseVetoException();
+ }
+}
+
+void SAL_CALL ODocumentDefinition::notifyClosing( const lang::EventObject& /*Source*/ ) throw (uno::RuntimeException)
+{
+}
+
+void SAL_CALL ODocumentDefinition::disposing( const lang::EventObject& /*Source*/ ) throw (uno::RuntimeException)
+{
+}
+
+void ODocumentDefinition::firePropertyChange( sal_Int32 i_nHandle, const Any& i_rNewValue, const Any& i_rOldValue,
+ sal_Bool i_bVetoable, const NotifierAccess )
+{
+ fire( &i_nHandle, &i_rNewValue, &i_rOldValue, 1, i_bVetoable );
+}
+
+// =============================================================================
+// NameChangeNotifier
+// =============================================================================
+NameChangeNotifier::NameChangeNotifier( ODocumentDefinition& i_rDocumentDefinition, const ::rtl::OUString& i_rNewName,
+ ::osl::ResettableMutexGuard& i_rClearForNotify )
+ :m_rDocumentDefinition( i_rDocumentDefinition )
+ ,m_aOldValue( makeAny( i_rDocumentDefinition.getCurrentName() ) )
+ ,m_aNewValue( makeAny( i_rNewName ) )
+ ,m_rClearForNotify( i_rClearForNotify )
+{
+ impl_fireEvent_throw( sal_True );
+}
+
+NameChangeNotifier::~NameChangeNotifier()
+{
+ impl_fireEvent_throw( sal_False );
+}
+
+void NameChangeNotifier::impl_fireEvent_throw( const sal_Bool i_bVetoable )
+{
+ m_rClearForNotify.clear();
+ m_rDocumentDefinition.firePropertyChange(
+ PROPERTY_ID_NAME, m_aNewValue, m_aOldValue, i_bVetoable, ODocumentDefinition::NotifierAccess() );
+ m_rClearForNotify.reset();
+}
+
+} // namespace dbaccess
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/documentdefinition.hxx b/dbaccess/source/core/dataaccess/documentdefinition.hxx
new file mode 100644
index 000000000000..f74b6acf6815
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/documentdefinition.hxx
@@ -0,0 +1,386 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _DBA_COREDATAACCESS_DOCUMENTDEFINITION_HXX_
+#define _DBA_COREDATAACCESS_DOCUMENTDEFINITION_HXX_
+
+#include <cppuhelper/propshlp.hxx>
+#include <cppuhelper/implbase4.hxx>
+#include "ContentHelper.hxx"
+#include <comphelper/propertystatecontainer.hxx>
+#include <comphelper/proparrhlp.hxx>
+#include "apitools.hxx"
+#include <comphelper/uno3.hxx>
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <com/sun/star/frame/XComponentLoader.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/embed/XStateChangeListener.hpp>
+#include <com/sun/star/sdb/XSubDocument.hpp>
+#include <com/sun/star/util/XCloseListener.hpp>
+#include <com/sun/star/container/XHierarchicalName.hpp>
+
+namespace comphelper
+{
+ class NamedValueCollection;
+}
+
+//........................................................................
+namespace dbaccess
+{
+//........................................................................
+
+ class OInterceptor;
+ class OEmbeddedClientHelper;
+//==========================================================================
+//= ODocumentDefinition - a database "document" which is simply a link to a real
+//= document
+//==========================================================================
+
+typedef ::cppu::ImplHelper4 < ::com::sun::star::embed::XComponentSupplier
+ , ::com::sun::star::sdb::XSubDocument
+ , ::com::sun::star::util::XCloseListener
+ , ::com::sun::star::container::XHierarchicalName
+ > ODocumentDefinition_Base;
+
+class ODocumentDefinition
+ :public OContentHelper
+ ,public ::comphelper::OPropertyStateContainer
+ ,public ::comphelper::OPropertyArrayUsageHelper< ODocumentDefinition >
+ ,public ODocumentDefinition_Base
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::embed::XEmbeddedObject> m_xEmbeddedObject;
+ ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStateChangeListener > m_xListener;
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > m_xLastKnownConnection;
+
+ OInterceptor* m_pInterceptor;
+ sal_Bool m_bForm; // <TRUE/> if it is a form
+ sal_Bool m_bOpenInDesign;
+ sal_Bool m_bInExecute;
+ sal_Bool m_bRemoveListener;
+ OEmbeddedClientHelper* m_pClientHelper;
+
+protected:
+ virtual ~ODocumentDefinition();
+
+public:
+
+ ODocumentDefinition(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxContainer,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&,
+ const TContentPtr& _pImpl,
+ sal_Bool _bForm
+ );
+
+ void initialLoad(
+ const ::com::sun::star::uno::Sequence< sal_Int8 >& i_rClassID,
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& i_rCreationArgs,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& i_rConnection
+ );
+
+// com::sun::star::lang::XTypeProvider
+ DECLARE_TYPEPROVIDER( );
+
+// ::com::sun::star::uno::XInterface
+ DECLARE_XINTERFACE( )
+
+// ::com::sun::star::lang::XServiceInfo
+ DECLARE_SERVICE_INFO_STATIC();
+
+// ::com::sun::star::beans::XPropertySet
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) throw(::com::sun::star::uno::RuntimeException);
+
+ // OPropertySetHelper
+ virtual void SAL_CALL getFastPropertyValue(
+ ::com::sun::star::uno::Any& o_rValue,
+ sal_Int32 i_nHandle
+ ) const;
+
+ // XComponentSupplier
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloseable > SAL_CALL getComponent( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XSubDocument
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > SAL_CALL open( ) throw (::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > SAL_CALL openDesign( ) throw (::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL store( ) throw (::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL close( ) throw (::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+ // XHierarchicalName
+ virtual ::rtl::OUString SAL_CALL getHierarchicalName( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL composeHierarchicalName( const ::rtl::OUString& aRelativeName ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException);
+
+// OPropertySetHelper
+ virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
+
+ // XCommandProcessor
+ virtual ::com::sun::star::uno::Any SAL_CALL execute( const ::com::sun::star::ucb::Command& aCommand, sal_Int32 CommandId, const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >& Environment ) throw (::com::sun::star::uno::Exception, ::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::RuntimeException) ;
+
+ // XRename
+ virtual void SAL_CALL rename( const ::rtl::OUString& newName ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException);
+
+ // XCloseListener
+ virtual void SAL_CALL queryClosing( const ::com::sun::star::lang::EventObject& Source, ::sal_Bool GetsOwnership ) throw (::com::sun::star::util::CloseVetoException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL notifyClosing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);
+
+ /** returns the forms/reports container storage, depending on m_bForm. Our own storage
+ inside this container storage is the one with the name as indicated by m_pImpl->m_aProps.sPersistentName.
+ */
+ ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >
+ getContainerStorage() const;
+
+ sal_Bool save(sal_Bool _bApprove);
+ sal_Bool saveAs();
+ void closeObject();
+ sal_Bool isModified();
+ inline sal_Bool isNewReport() const { return !m_bForm && !m_pImpl->m_aProps.bAsTemplate; }
+
+ static void fillReportData(
+ const ::comphelper::ComponentContext& _rContext,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloseable >& _rxComponent,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxActiveConnection
+ );
+
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >&
+ getConnection() const { return m_xLastKnownConnection; }
+
+ /** prepares closing the document component
+
+ The method suspends the controller associated with the document, and saves the document
+ if necessary.
+
+ @return
+ <TRUE/> if and only if the document component can be closed
+ */
+ bool prepareClose();
+
+ static ::com::sun::star::uno::Sequence< sal_Int8 > getDefaultDocumentTypeClassId();
+
+ static ::rtl::OUString GetDocumentServiceFromMediaType(
+ const ::rtl::OUString& _rMediaType,
+ const ::comphelper::ComponentContext& _rContext,
+ ::com::sun::star::uno::Sequence< sal_Int8 >& _rClassId
+ );
+ static ::rtl::OUString GetDocumentServiceFromMediaType(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& _rxContainerStorage,
+ const ::rtl::OUString& _rEntityName,
+ const ::comphelper::ComponentContext& _rContext,
+ ::com::sun::star::uno::Sequence< sal_Int8 >& _rClassId
+ );
+
+ struct NotifierAccess { friend class NameChangeNotifier; private: NotifierAccess() { } };
+ const ::rtl::OUString& getCurrentName() const { return m_pImpl->m_aProps.aTitle; }
+ void firePropertyChange(
+ sal_Int32 i_nHandle,
+ const ::com::sun::star::uno::Any& i_rNewValue,
+ const ::com::sun::star::uno::Any& i_rOldValue,
+ sal_Bool i_bVetoable,
+ const NotifierAccess
+ );
+
+private:
+ /** does necessary initializations after our embedded object has been switched to ACTIVE
+ */
+ void impl_onActivateEmbeddedObject_nothrow( const bool i_bReactivated );
+
+ /** initializes a newly created view/controller of a form which is displaying our embedded object
+
+ Has only to be called if the respective embedded object has been loaded for design (and
+ not for data entry)
+
+ @param _rxController
+ the controller which belongs to the XModel of our (active) embedded object
+ */
+ static void impl_initFormEditView( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController >& _rxController );
+
+ /** removes the given frame from the desktop's frame collection
+ @raises ::com::sun::star::uno::RuntimeException
+ */
+ static void impl_removeFrameFromDesktop_throw(
+ const ::comphelper::ComponentContext& _rContxt,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& _rxFrame
+ );
+
+ /** opens the UI for this sub document
+ */
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >
+ impl_openUI_nolck_throw( bool _bForEditing );
+
+ /** stores our document, if it's already loaded
+ */
+ void impl_store_throw();
+
+ /** closes our document, if it's open
+ */
+ bool impl_close_throw();
+
+ /** returns our component, creates it if necessary
+ */
+ ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloseable >
+ impl_getComponent_throw( const bool i_ForceCreate = true );
+
+ /** shows or hides our component
+
+ The embedded object must exist, and be in state LOADED, at least.
+ */
+ void impl_showOrHideComponent_throw( const bool i_bShow );
+
+ // OPropertyArrayUsageHelper
+ virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;
+
+ virtual void getPropertyDefaultByHandle( sal_Int32 _nHandle, ::com::sun::star::uno::Any& _rDefault ) const;
+
+ // helper
+ virtual void SAL_CALL disposing();
+
+ // OContentHelper overridables
+ virtual ::rtl::OUString determineContentType() const;
+
+ /** fills the load arguments
+ */
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >
+ fillLoadArgs(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection>& _xConnection,
+ const bool _bSuppressMacros,
+ const bool _bReadOnly,
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& i_rOpenCommandArguments,
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& _out_rEmbeddedObjectDescriptor
+ );
+
+ /** splits the given arguments to an "open*" command into arguments for loading the document, and arguments to be
+ put into the EmbeddedObjectDescriptor
+
+ Any values already present in <code>o_rDocumentLoadArgs</code> and <code>o_rEmbeddedObjectDescriptor</code>
+ will be overwritten by values from <code>i_rOpenCommandArguments</code>, if applicable, otherwise they will
+ be preserved.
+
+ @param i_rOpenCommandArguments
+ the arguments passed to the "open*" command at the content
+ @param o_rDocumentLoadArgs
+ the arguments to be passed when actually loading the embedded document.
+ @param o_rEmbeddedObjectDescriptor
+ the EmbeddedObjectDescriptor to be passed when initializing the embedded object
+ */
+ void separateOpenCommandArguments(
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& i_rOpenCommandArguments,
+ ::comphelper::NamedValueCollection& o_rDocumentLoadArgs,
+ ::comphelper::NamedValueCollection& o_rEmbeddedObjectDescriptor
+ );
+
+ /** loads the EmbeddedObject if not already loaded
+ @param _aClassID
+ If set, it will be used to create the embedded object.
+ */
+ void loadEmbeddedObject(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection>& _xConnection,
+ const ::com::sun::star::uno::Sequence< sal_Int8 >& _aClassID,
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& _rAdditionalArgs,
+ const bool _bSuppressMacros,
+ const bool _bReadOnly
+ );
+
+ /** loads the embedded object, if not already loaded. No new object can be created with this method.
+ */
+ void loadEmbeddedObject( bool _bSuppressMacros = false )
+ {
+ loadEmbeddedObject(
+ NULL,
+ ::com::sun::star::uno::Sequence< sal_Int8 >(),
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >(),
+ _bSuppressMacros,
+ false
+ );
+ }
+
+ /** loads the embedded object for preview. Macros will be suppressed, and the document will
+ be read-only.
+ */
+ void loadEmbeddedObjectForPreview()
+ {
+ loadEmbeddedObject(
+ NULL,
+ ::com::sun::star::uno::Sequence< sal_Int8 >(),
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >(),
+ true,
+ true
+ );
+ }
+
+ /** searches for read-only flag in the args of the model and sets it to the given value,
+ if the value was not found, it will be appended.
+ @param _bReadOnly
+ If <TRUE/> the document will be switched to readonly mode
+ */
+ void updateDocumentTitle();
+
+ void registerProperties();
+
+ /** determines whether the document we represent supports embedded scripts and macros
+ */
+ sal_Bool objectSupportsEmbeddedScripts() const;
+
+ //- commands
+
+ void onCommandGetDocumentProperties( ::com::sun::star::uno::Any& _rProps );
+ void onCommandInsert( const ::rtl::OUString& _sURL, const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >& Environment ) throw( ::com::sun::star::uno::Exception );
+ void onCommandPreview( ::com::sun::star::uno::Any& _rImage );
+ ::com::sun::star::uno::Any
+ onCommandOpenSomething(
+ const ::com::sun::star::uno::Any& _rArgument,
+ const bool _bActivate,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >& _rxEnvironment
+ );
+private:
+ using ::cppu::OPropertySetHelper::getFastPropertyValue;
+};
+
+class NameChangeNotifier
+{
+public:
+ NameChangeNotifier(
+ ODocumentDefinition& i_rDocumentDefinition,
+ const ::rtl::OUString& i_rNewName,
+ ::osl::ResettableMutexGuard& i_rClearForNotify
+ );
+ ~NameChangeNotifier();
+
+private:
+ ODocumentDefinition& m_rDocumentDefinition;
+ const ::com::sun::star::uno::Any m_aOldValue;
+ const ::com::sun::star::uno::Any m_aNewValue;
+ mutable ::osl::ResettableMutexGuard& m_rClearForNotify;
+
+ void impl_fireEvent_throw( const sal_Bool i_bVetoable );
+};
+
+} // namespace dbaccess
+
+#endif // _DBA_COREDATAACCESS_DOCUMENTDEFINITION_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/documenteventexecutor.cxx b/dbaccess/source/core/dataaccess/documenteventexecutor.cxx
new file mode 100644
index 000000000000..35262dd70038
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/documenteventexecutor.cxx
@@ -0,0 +1,222 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ * 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"
+
+#include "documenteventexecutor.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/document/XDocumentEventBroadcaster.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/componentcontext.hxx>
+#include <comphelper/namedvaluecollection.hxx>
+#include <cppuhelper/weakref.hxx>
+#include <tools/diagnose_ex.h>
+#include <vcl/svapp.hxx>
+#include <osl/mutex.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::uno::WeakReference;
+ using ::com::sun::star::document::XDocumentEventBroadcaster;
+ using ::com::sun::star::document::XEventsSupplier;
+ using ::com::sun::star::container::XNameAccess;
+ using ::com::sun::star::frame::XModel;
+ using ::com::sun::star::util::XURLTransformer;
+ using ::com::sun::star::frame::XDispatchProvider;
+ using ::com::sun::star::frame::XDispatch;
+ using ::com::sun::star::util::URL;
+ using ::com::sun::star::beans::PropertyValue;
+ using ::com::sun::star::frame::XController;
+ using ::com::sun::star::document::DocumentEvent;
+ /** === end UNO using === **/
+ using namespace ::com::sun::star;
+
+ //====================================================================
+ //= DocumentEventExecutor_Data
+ //====================================================================
+ struct DocumentEventExecutor_Data
+ {
+ WeakReference< XEventsSupplier > xDocument;
+ Reference< XURLTransformer > xURLTransformer;
+
+ DocumentEventExecutor_Data( const Reference< XEventsSupplier >& _rxDocument )
+ :xDocument( _rxDocument )
+ {
+ }
+ };
+
+ namespace
+ {
+ static void lcl_dispatchScriptURL_throw( DocumentEventExecutor_Data& _rDocExecData,
+ const ::rtl::OUString& _rScriptURL, const DocumentEvent& _rTrigger )
+ {
+ Reference< XModel > xDocument( _rDocExecData.xDocument.get(), UNO_QUERY_THROW );
+
+ Reference< XController > xController( xDocument->getCurrentController() );
+ Reference< XDispatchProvider > xDispProv;
+ if ( xController.is() )
+ xDispProv.set( xController->getFrame(), UNO_QUERY );
+ if ( !xDispProv.is() )
+ {
+ OSL_ENSURE( false, "lcl_dispatchScriptURL_throw: no controller/frame? How should I dispatch?" );
+ return;
+ }
+
+ URL aScriptURL;
+ aScriptURL.Complete = _rScriptURL;
+ if ( _rDocExecData.xURLTransformer.is() )
+ _rDocExecData.xURLTransformer->parseStrict( aScriptURL );
+
+ // unfortunately, executing a script can trigger all kind of complex stuff, and unfortunately, not
+ // every component involved into this properly cares for thread safety. To be on the safe side,
+ // we lock the solar mutex here.
+ SolarMutexGuard aSolarGuard;
+
+ Reference< XDispatch > xDispatch( xDispProv->queryDispatch( aScriptURL, ::rtl::OUString(), 0 ) );
+ if ( !xDispatch.is() )
+ {
+ OSL_ENSURE( false, "lcl_dispatchScriptURL_throw: no dispatcher for the script URL!" );
+ return;
+ }
+
+ PropertyValue aEventParam;
+ aEventParam.Value <<= _rTrigger;
+ Sequence< PropertyValue > aDispatchArgs( &aEventParam, 1 );
+ xDispatch->dispatch( aScriptURL, aDispatchArgs );
+ }
+ }
+
+ //====================================================================
+ //= DocumentEventExecutor
+ //====================================================================
+ DocumentEventExecutor::DocumentEventExecutor( const ::comphelper::ComponentContext& _rContext,
+ const Reference< XEventsSupplier >& _rxDocument )
+ :m_pData( new DocumentEventExecutor_Data( _rxDocument ) )
+ {
+ Reference< XDocumentEventBroadcaster > xBroadcaster( _rxDocument, UNO_QUERY_THROW );
+
+ osl_incrementInterlockedCount( &m_refCount );
+ {
+ xBroadcaster->addDocumentEventListener( this );
+ }
+ osl_decrementInterlockedCount( &m_refCount );
+
+ try
+ {
+ _rContext.createComponent( "com.sun.star.util.URLTransformer", m_pData->xURLTransformer );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ DocumentEventExecutor::~DocumentEventExecutor()
+ {
+ }
+
+ void SAL_CALL DocumentEventExecutor::documentEventOccured( const DocumentEvent& _Event ) throw (RuntimeException)
+ {
+ Reference< XEventsSupplier > xEventsSupplier( m_pData->xDocument.get(), UNO_QUERY );
+ if ( !xEventsSupplier.is() )
+ {
+ OSL_ENSURE( false, "DocumentEventExecutor::documentEventOccured: no document anymore, but still being notified?" );
+ return;
+ }
+
+ Reference< XModel > xDocument( xEventsSupplier, UNO_QUERY_THROW );
+
+ try
+ {
+ Reference< XNameAccess > xDocEvents( xEventsSupplier->getEvents().get(), UNO_SET_THROW );
+ if ( !xDocEvents->hasByName( _Event.EventName ) )
+ {
+ // this is worth an assertion: We are listener at the very same document which we just asked
+ // for its events. So when EventName is fired, why isn't it supported by xDocEvents?
+ OSL_ENSURE( false, "DocumentEventExecutor::documentEventOccured: an unsupported event is notified!" );
+ return;
+ }
+
+ const ::comphelper::NamedValueCollection aScriptDescriptor( xDocEvents->getByName( _Event.EventName ) );
+
+ ::rtl::OUString sEventType;
+ bool bScriptAssigned = aScriptDescriptor.get_ensureType( "EventType", sEventType );
+
+ ::rtl::OUString sScript;
+ bScriptAssigned = bScriptAssigned && aScriptDescriptor.get_ensureType( "Script", sScript );
+
+ if ( !bScriptAssigned )
+ // no script is assigned to this event
+ return;
+
+ bool bDispatchScriptURL =
+ ( sEventType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Script" ) )
+ || sEventType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Service" ) )
+ );
+ bool bNonEmptyScript = sScript.getLength() != 0;
+
+ OSL_ENSURE( bDispatchScriptURL && bNonEmptyScript,
+ "DocumentEventExecutor::documentEventOccured: invalid/unsupported script descriptor" );
+
+ if ( bDispatchScriptURL && bNonEmptyScript )
+ {
+ lcl_dispatchScriptURL_throw( *m_pData, sScript, _Event );
+ }
+ }
+ catch( const RuntimeException& ) { throw; }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ void SAL_CALL DocumentEventExecutor::disposing( const lang::EventObject& /*_Source*/ ) throw (RuntimeException)
+ {
+ // not interested in
+ }
+
+} // namespace dbaccess
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/documenteventexecutor.hxx b/dbaccess/source/core/dataaccess/documenteventexecutor.hxx
new file mode 100644
index 000000000000..c83a3e2886fd
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/documenteventexecutor.hxx
@@ -0,0 +1,77 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ * 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.
+ *
+************************************************************************/
+
+#ifndef DBACCESS_DOCUMENTEVENTEXECUTOR_HXX
+#define DBACCESS_DOCUMENTEVENTEXECUTOR_HXX
+
+/** === begin UNO includes === **/
+#include <com/sun/star/document/XDocumentEventListener.hpp>
+#include <com/sun/star/document/XEventsSupplier.hpp>
+/** === end UNO includes === **/
+
+#include <cppuhelper/implbase1.hxx>
+
+#include <memory>
+
+namespace comphelper
+{
+ class ComponentContext;
+}
+
+namespace dbaccess
+{
+
+ struct DocumentEventExecutor_Data;
+ //====================================================================
+ //= DocumentEventExecutor
+ //====================================================================
+ typedef ::cppu::WeakImplHelper1 < ::com::sun::star::document::XDocumentEventListener
+ > DocumentEventExecutor_Base;
+ class DocumentEventExecutor : public DocumentEventExecutor_Base
+ {
+ public:
+ DocumentEventExecutor(
+ const ::comphelper::ComponentContext& _rContext,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::document::XEventsSupplier >& _rxDocument );
+
+ protected:
+ virtual ~DocumentEventExecutor();
+
+ // css.document.XDocumentEventListener
+ virtual void SAL_CALL documentEventOccured( const ::com::sun::star::document::DocumentEvent& Event ) throw (::com::sun::star::uno::RuntimeException);
+ // css.lang.XEventListener
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);
+
+ private:
+ ::std::auto_ptr< DocumentEventExecutor_Data > m_pData;
+ };
+
+} // namespace dbaccess
+
+#endif // DBACCESS_DOCUMENTEVENTEXECUTOR_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/documenteventnotifier.cxx b/dbaccess/source/core/dataaccess/documenteventnotifier.cxx
new file mode 100644
index 000000000000..dabd16a934fb
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/documenteventnotifier.cxx
@@ -0,0 +1,300 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ * 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"
+
+#include "documenteventnotifier.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/frame/DoubleInitializationException.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/asyncnotification.hxx>
+#include <cppuhelper/interfacecontainer.hxx>
+#include <cppuhelper/weak.hxx>
+#include <tools/diagnose_ex.h>
+
+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::frame::DoubleInitializationException;
+ using ::com::sun::star::document::XDocumentEventListener;
+ using ::com::sun::star::document::DocumentEvent;
+ using ::com::sun::star::frame::XController2;
+ /** === end UNO using === **/
+ using namespace ::com::sun::star;
+
+ //==================================================================
+ //= DocumentEventHolder
+ //==================================================================
+ typedef ::comphelper::EventHolder< DocumentEvent > DocumentEventHolder;
+
+ //====================================================================
+ //= DocumentEventNotifier_Impl
+ //====================================================================
+ class DocumentEventNotifier_Impl : public ::comphelper::IEventProcessor
+ {
+ oslInterlockedCount m_refCount;
+ ::cppu::OWeakObject& m_rDocument;
+ ::osl::Mutex& m_rMutex;
+ bool m_bInitialized;
+ bool m_bDisposed;
+ ::rtl::Reference< ::comphelper::AsyncEventNotifier > m_pEventBroadcaster;
+ ::cppu::OInterfaceContainerHelper m_aLegacyEventListeners;
+ ::cppu::OInterfaceContainerHelper m_aDocumentEventListeners;
+
+ public:
+ DocumentEventNotifier_Impl( ::cppu::OWeakObject& _rBroadcasterDocument, ::osl::Mutex& _rMutex )
+ :m_refCount( 0 )
+ ,m_rDocument( _rBroadcasterDocument )
+ ,m_rMutex( _rMutex )
+ ,m_bInitialized( false )
+ ,m_bDisposed( false )
+ ,m_aLegacyEventListeners( _rMutex )
+ ,m_aDocumentEventListeners( _rMutex )
+ {
+ }
+
+ // IReference
+ virtual void SAL_CALL acquire();
+ virtual void SAL_CALL release();
+
+ void addLegacyEventListener( const Reference< document::XEventListener >& _Listener )
+ {
+ m_aLegacyEventListeners.addInterface( _Listener );
+ }
+
+ void removeLegacyEventListener( const Reference< document::XEventListener >& _Listener )
+ {
+ m_aLegacyEventListeners.removeInterface( _Listener );
+ }
+
+ void addDocumentEventListener( const Reference< XDocumentEventListener >& _Listener )
+ {
+ m_aDocumentEventListeners.addInterface( _Listener );
+ }
+
+ void removeDocumentEventListener( const Reference< XDocumentEventListener >& _Listener )
+ {
+ m_aDocumentEventListeners.removeInterface( _Listener );
+ }
+
+ void disposing();
+
+ void onDocumentInitialized();
+
+ void notifyDocumentEvent( const ::rtl::OUString& _EventName, const Reference< XController2 >& _ViewController,
+ const Any& _Supplement )
+ {
+ impl_notifyEvent_nothrow( DocumentEvent(
+ m_rDocument, _EventName, _ViewController, _Supplement ) );
+ }
+
+ void notifyDocumentEventAsync( const ::rtl::OUString& _EventName, const Reference< XController2 >& _ViewController,
+ const Any& _Supplement )
+ {
+ impl_notifyEventAsync_nothrow( DocumentEvent(
+ m_rDocument, _EventName, _ViewController, _Supplement ) );
+ }
+
+ protected:
+ virtual ~DocumentEventNotifier_Impl()
+ {
+ }
+
+ // IEventProcessor
+ virtual void processEvent( const ::comphelper::AnyEvent& _rEvent );
+
+ private:
+ void impl_notifyEvent_nothrow( const DocumentEvent& _rEvent );
+ void impl_notifyEventAsync_nothrow( const DocumentEvent& _rEvent );
+ };
+
+ void SAL_CALL DocumentEventNotifier_Impl::acquire()
+ {
+ osl_incrementInterlockedCount( &m_refCount );
+ }
+
+ void SAL_CALL DocumentEventNotifier_Impl::release()
+ {
+ if ( 0 == osl_decrementInterlockedCount( &m_refCount ) )
+ delete this;
+ }
+
+ void DocumentEventNotifier_Impl::disposing()
+ {
+ // SYNCHRONIZED ->
+ // cancel any pending asynchronous events
+ ::osl::ResettableMutexGuard aGuard( m_rMutex );
+ if ( m_pEventBroadcaster.is() )
+ {
+ m_pEventBroadcaster->removeEventsForProcessor( this );
+ m_pEventBroadcaster->terminate();
+ m_pEventBroadcaster = NULL;
+ }
+
+ lang::EventObject aEvent( m_rDocument );
+ aGuard.clear();
+ // <-- SYNCHRONIZED
+
+ m_aLegacyEventListeners.disposeAndClear( aEvent );
+ m_aDocumentEventListeners.disposeAndClear( aEvent );
+
+ // SYNCHRONIZED ->
+ aGuard.reset();
+ m_bDisposed = true;
+ // <-- SYNCHRONIZED
+ }
+
+ void DocumentEventNotifier_Impl::onDocumentInitialized()
+ {
+ if ( m_bInitialized )
+ throw DoubleInitializationException();
+
+ m_bInitialized = true;
+ if ( m_pEventBroadcaster.is() )
+ // there are already pending asynchronous events
+ m_pEventBroadcaster->create();
+ }
+
+ void DocumentEventNotifier_Impl::impl_notifyEvent_nothrow( const DocumentEvent& _rEvent )
+ {
+ OSL_PRECOND( m_bInitialized,
+ "DocumentEventNotifier_Impl::impl_notifyEvent_nothrow: only to be called when the document is already initialized!" );
+ try
+ {
+ document::EventObject aLegacyEvent( _rEvent.Source, _rEvent.EventName );
+ m_aLegacyEventListeners.notifyEach( &document::XEventListener::notifyEvent, aLegacyEvent );
+ }
+ catch(const Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ try
+ {
+ m_aDocumentEventListeners.notifyEach( &XDocumentEventListener::documentEventOccured, _rEvent );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ void DocumentEventNotifier_Impl::impl_notifyEventAsync_nothrow( const DocumentEvent& _rEvent )
+ {
+ if ( !m_pEventBroadcaster.is() )
+ {
+ m_pEventBroadcaster.set( new ::comphelper::AsyncEventNotifier );
+ if ( m_bInitialized )
+ // start processing the events if and only if we (our document, respectively) are
+ // already initialized
+ m_pEventBroadcaster->create();
+ }
+ m_pEventBroadcaster->addEvent( new DocumentEventHolder( _rEvent ), this );
+ }
+
+ void DocumentEventNotifier_Impl::processEvent( const ::comphelper::AnyEvent& _rEvent )
+ {
+ // beware, this is called from the notification thread
+ {
+ ::osl::MutexGuard aGuard( m_rMutex );
+ if ( m_bDisposed )
+ return;
+ }
+ const DocumentEventHolder& rEventHolder = dynamic_cast< const DocumentEventHolder& >( _rEvent );
+ impl_notifyEvent_nothrow( rEventHolder.getEventObject() );
+ }
+
+ //====================================================================
+ //= DocumentEventNotifier
+ //====================================================================
+ DocumentEventNotifier::DocumentEventNotifier( ::cppu::OWeakObject& _rBroadcasterDocument, ::osl::Mutex& _rMutex )
+ :m_pImpl( new DocumentEventNotifier_Impl( _rBroadcasterDocument, _rMutex ) )
+ {
+ }
+
+ DocumentEventNotifier::~DocumentEventNotifier()
+ {
+ }
+
+ void DocumentEventNotifier::disposing()
+ {
+ m_pImpl->disposing();
+ }
+
+ void DocumentEventNotifier::onDocumentInitialized()
+ {
+ m_pImpl->onDocumentInitialized();
+ }
+
+ void DocumentEventNotifier::addLegacyEventListener( const Reference< document::XEventListener >& _Listener )
+ {
+ m_pImpl->addLegacyEventListener( _Listener );
+ }
+
+ void DocumentEventNotifier::removeLegacyEventListener( const Reference< document::XEventListener >& _Listener )
+ {
+ m_pImpl->removeLegacyEventListener( _Listener );
+ }
+
+ void DocumentEventNotifier::addDocumentEventListener( const Reference< XDocumentEventListener >& _Listener )
+ {
+ m_pImpl->addDocumentEventListener( _Listener );
+ }
+
+ void DocumentEventNotifier::removeDocumentEventListener( const Reference< XDocumentEventListener >& _Listener )
+ {
+ m_pImpl->removeDocumentEventListener( _Listener );
+ }
+
+ void DocumentEventNotifier::notifyDocumentEvent( const ::rtl::OUString& _EventName,
+ const Reference< XController2 >& _ViewController, const Any& _Supplement )
+ {
+ m_pImpl->notifyDocumentEvent( _EventName, _ViewController, _Supplement );
+ }
+
+ void DocumentEventNotifier::notifyDocumentEventAsync( const ::rtl::OUString& _EventName,
+ const Reference< XController2 >& _ViewController, const Any& _Supplement )
+ {
+ m_pImpl->notifyDocumentEventAsync( _EventName, _ViewController, _Supplement );
+ }
+
+} // namespace dbaccess
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/documenteventnotifier.hxx b/dbaccess/source/core/dataaccess/documenteventnotifier.hxx
new file mode 100644
index 000000000000..c92064aabbc7
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/documenteventnotifier.hxx
@@ -0,0 +1,143 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+/*************************************************************************
+ * 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.
+ *
+************************************************************************/
+
+#ifndef DBACCESS_DOCUMENTEVENTNOTIFIER_HXX
+#define DBACCESS_DOCUMENTEVENTNOTIFIER_HXX
+
+/** === begin UNO includes === **/
+#include <com/sun/star/document/XEventListener.hpp>
+#include <com/sun/star/document/XDocumentEventListener.hpp>
+/** === end UNO includes === **/
+
+#include <rtl/ref.hxx>
+
+namespace cppu
+{
+ class OWeakObject;
+}
+
+namespace dbaccess
+{
+
+ class DocumentEventNotifier_Impl;
+ //====================================================================
+ //= DocumentEventNotifier
+ //====================================================================
+ class DocumentEventNotifier
+ {
+ public:
+ DocumentEventNotifier( ::cppu::OWeakObject& _rBroadcasterDocument, ::osl::Mutex& _rMutex );
+ ~DocumentEventNotifier();
+
+ void addLegacyEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::document::XEventListener >& _Listener );
+ void removeLegacyEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::document::XEventListener >& _Listener );
+ void addDocumentEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::document::XDocumentEventListener >& _Listener );
+ void removeDocumentEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::document::XDocumentEventListener >& _Listener );
+
+ /** disposes the instance
+ @precond
+ the mutex is not locked
+ */
+ void disposing();
+
+ /** tells the instance that its document is completely initialized now.
+
+ Before you call this method, no notification will actually happen
+
+ @precond
+ the mutex is locked
+ */
+ void onDocumentInitialized();
+
+ /** notifies a document event described by the given parameters
+
+ @precond
+ the mutex is not locked
+ @precond
+ ->onDocumentInitialized has been called
+ */
+ void notifyDocumentEvent(
+ const ::rtl::OUString& _EventName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController2 >& _rxViewController = NULL,
+ const ::com::sun::star::uno::Any& _Supplement = ::com::sun::star::uno::Any()
+ );
+
+ /** notifies a document event, described by the given parameters, asynchronously
+
+ Note that no event is actually notified before you called ->onDocumentInitialized.
+
+ @precond
+ the mutex is locked
+ */
+ void notifyDocumentEventAsync(
+ const ::rtl::OUString& _EventName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController2 >& _ViewController = NULL,
+ const ::com::sun::star::uno::Any& _Supplement = ::com::sun::star::uno::Any()
+ );
+
+ /** notifies a document event to all registered listeners
+
+ @precond
+ the mutex is not locked
+ @precond
+ ->onDocumentInitialized has been called
+ */
+ void notifyDocumentEvent(
+ const sal_Char* _pAsciiEventName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController2 >& _rxViewController = NULL,
+ const ::com::sun::star::uno::Any& _rSupplement = ::com::sun::star::uno::Any()
+ )
+ {
+ notifyDocumentEvent( ::rtl::OUString::createFromAscii( _pAsciiEventName ), _rxViewController, _rSupplement );
+ }
+
+ /** notifies a document event to all registered listeners, asynchronously
+
+ Note that no event is actually notified before you called ->onDocumentInitialized.
+
+ @precond
+ the mutex is locked
+ */
+ void notifyDocumentEventAsync(
+ const sal_Char* _pAsciiEventName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController2 >& _rxViewController = NULL,
+ const ::com::sun::star::uno::Any& _rSupplement = ::com::sun::star::uno::Any()
+ )
+ {
+ notifyDocumentEventAsync( ::rtl::OUString::createFromAscii( _pAsciiEventName ), _rxViewController, _rSupplement );
+ }
+
+ private:
+ ::rtl::Reference< DocumentEventNotifier_Impl > m_pImpl;
+ };
+
+} // namespace dbaccess
+
+#endif // DBACCESS_DOCUMENTEVENTNOTIFIER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/documentevents.cxx b/dbaccess/source/core/dataaccess/documentevents.cxx
new file mode 100644
index 000000000000..208b2486c459
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/documentevents.cxx
@@ -0,0 +1,250 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ * 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"
+
+#include "documentevents.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/beans/PropertyValue.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/namedvaluecollection.hxx>
+
+#include <algorithm>
+#include <functional>
+
+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::beans::PropertyValue;
+ using ::com::sun::star::container::NoSuchElementException;
+ using ::com::sun::star::lang::WrappedTargetException;
+ using ::com::sun::star::lang::IllegalArgumentException;
+ using ::com::sun::star::uno::Sequence;
+ using ::com::sun::star::uno::Type;
+ /** === end UNO using === **/
+
+ //====================================================================
+ //= DocumentEvents_Data
+ //====================================================================
+ struct DocumentEvents_Data : public ::boost::noncopyable
+ {
+ ::cppu::OWeakObject& rParent;
+ ::osl::Mutex& rMutex;
+ DocumentEventsData& rEventsData;
+
+ DocumentEvents_Data( ::cppu::OWeakObject& _rParent, ::osl::Mutex& _rMutex, DocumentEventsData& _rEventsData )
+ :rParent( _rParent )
+ ,rMutex( _rMutex )
+ ,rEventsData( _rEventsData )
+ {
+ }
+ };
+
+ //====================================================================
+ //= helper
+ //====================================================================
+ struct DocumentEventData
+ {
+ const sal_Char* pAsciiEventName;
+ bool bNeedsSyncNotify;
+ };
+
+ namespace
+ {
+ static const DocumentEventData* lcl_getDocumentEventData()
+ {
+ static const DocumentEventData s_aData[] = {
+ { "OnCreate", true },
+ { "OnLoadFinished", true },
+ { "OnNew", false }, // compatibility, see http://www.openoffice.org/issues/show_bug.cgi?id=46484
+ { "OnLoad", false }, // compatibility, see http://www.openoffice.org/issues/show_bug.cgi?id=46484
+ { "OnSaveAs", true },
+ { "OnSaveAsDone", false },
+ { "OnSaveAsFailed", false },
+ { "OnSave", true },
+ { "OnSaveDone", false },
+ { "OnSaveFailed", false },
+ { "OnSaveTo", true },
+ { "OnSaveToDone", false },
+ { "OnSaveToFailed", false },
+ { "OnPrepareUnload", true },
+ { "OnUnload", true },
+ { "OnFocus", false },
+ { "OnUnfocus", false },
+ { "OnModifyChanged", false },
+ { "OnViewCreated", false },
+ { "OnPrepareViewClosing", true },
+ { "OnViewClosed", false },
+ { "OnTitleChanged", false },
+ { "OnSubComponentOpened", false },
+ { "OnSubComponentClosed", false },
+ { NULL, false }
+ };
+ return s_aData;
+ }
+ }
+
+ //====================================================================
+ //= DocumentEvents
+ //====================================================================
+ DocumentEvents::DocumentEvents( ::cppu::OWeakObject& _rParent, ::osl::Mutex& _rMutex, DocumentEventsData& _rEventsData )
+ :m_pData( new DocumentEvents_Data( _rParent, _rMutex, _rEventsData ) )
+ {
+ const DocumentEventData* pEventData = lcl_getDocumentEventData();
+ while ( pEventData->pAsciiEventName )
+ {
+ ::rtl::OUString sEventName = ::rtl::OUString::createFromAscii( pEventData->pAsciiEventName );
+ DocumentEventsData::iterator existingPos = m_pData->rEventsData.find( sEventName );
+ if ( existingPos == m_pData->rEventsData.end() )
+ m_pData->rEventsData[ sEventName ] = Sequence< PropertyValue >();
+ ++pEventData;
+ }
+ }
+
+ DocumentEvents::~DocumentEvents()
+ {
+ }
+
+ void SAL_CALL DocumentEvents::acquire() throw()
+ {
+ m_pData->rParent.acquire();
+ }
+
+ void SAL_CALL DocumentEvents::release() throw()
+ {
+ m_pData->rParent.release();
+ }
+
+ bool DocumentEvents::needsSynchronousNotification( const ::rtl::OUString& _rEventName )
+ {
+ const DocumentEventData* pEventData = lcl_getDocumentEventData();
+ while ( pEventData->pAsciiEventName )
+ {
+ if ( _rEventName.compareToAscii( pEventData->pAsciiEventName ) == 0 )
+ return pEventData->bNeedsSyncNotify;
+ ++pEventData;
+ }
+
+ // this is an unknown event ... assume async notification
+ return false;
+ }
+
+ void SAL_CALL DocumentEvents::replaceByName( const ::rtl::OUString& _Name, const Any& _Element ) throw (IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_pData->rMutex );
+
+ DocumentEventsData::iterator elementPos = m_pData->rEventsData.find( _Name );
+ if ( elementPos == m_pData->rEventsData.end() )
+ throw NoSuchElementException( _Name, *this );
+
+ Sequence< PropertyValue > aEventDescriptor;
+ if ( _Element.hasValue() && !( _Element >>= aEventDescriptor ) )
+ throw IllegalArgumentException( _Element.getValueTypeName(), *this, 2 );
+
+ // Weird enough, the event assignment UI has (well: had) the idea of using an empty "EventType"/"Script"
+ // to indicate the event descriptor should be reset, instead of just passing an empty event descriptor.
+ ::comphelper::NamedValueCollection aCheck( aEventDescriptor );
+ if ( aCheck.has( "EventType" ) )
+ {
+ ::rtl::OUString sEventType = aCheck.getOrDefault( "EventType", ::rtl::OUString() );
+ OSL_ENSURE( sEventType.getLength(), "DocumentEvents::replaceByName: doing a reset via an empty EventType is weird!" );
+ if ( !sEventType.getLength() )
+ aEventDescriptor.realloc( 0 );
+ }
+ if ( aCheck.has( "Script" ) )
+ {
+ ::rtl::OUString sScript = aCheck.getOrDefault( "Script", ::rtl::OUString() );
+ OSL_ENSURE( sScript.getLength(), "DocumentEvents::replaceByName: doing a reset via an empty Script is weird!" );
+ if ( !sScript.getLength() )
+ aEventDescriptor.realloc( 0 );
+ }
+
+ elementPos->second = aEventDescriptor;
+ }
+
+ Any SAL_CALL DocumentEvents::getByName( const ::rtl::OUString& _Name ) throw (NoSuchElementException, WrappedTargetException, RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_pData->rMutex );
+
+ DocumentEventsData::const_iterator elementPos = m_pData->rEventsData.find( _Name );
+ if ( elementPos == m_pData->rEventsData.end() )
+ throw NoSuchElementException( _Name, *this );
+
+ Any aReturn;
+ const Sequence< PropertyValue >& rEventDesc( elementPos->second );
+ if ( rEventDesc.getLength() > 0 )
+ aReturn <<= rEventDesc;
+ return aReturn;
+ }
+
+ Sequence< ::rtl::OUString > SAL_CALL DocumentEvents::getElementNames( ) throw (RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_pData->rMutex );
+
+ Sequence< ::rtl::OUString > aNames( m_pData->rEventsData.size() );
+ ::std::transform(
+ m_pData->rEventsData.begin(),
+ m_pData->rEventsData.end(),
+ aNames.getArray(),
+ ::std::select1st< DocumentEventsData::value_type >()
+ );
+ return aNames;
+ }
+
+ ::sal_Bool SAL_CALL DocumentEvents::hasByName( const ::rtl::OUString& _Name ) throw (RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_pData->rMutex );
+
+ return m_pData->rEventsData.find( _Name ) != m_pData->rEventsData.end();
+ }
+
+ Type SAL_CALL DocumentEvents::getElementType( ) throw (RuntimeException)
+ {
+ return ::cppu::UnoType< Sequence< PropertyValue > >::get();
+ }
+
+ ::sal_Bool SAL_CALL DocumentEvents::hasElements( ) throw (RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_pData->rMutex );
+ return !m_pData->rEventsData.empty();
+ }
+
+} // namespace dbaccess
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/documentevents.hxx b/dbaccess/source/core/dataaccess/documentevents.hxx
new file mode 100644
index 000000000000..16cb0c86875e
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/documentevents.hxx
@@ -0,0 +1,89 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ * 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.
+ *
+************************************************************************/
+
+#ifndef DBACCESS_DOCUMENTEVENTS_HXX
+#define DBACCESS_DOCUMENTEVENTS_HXX
+
+/** === begin UNO includes === **/
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+/** === end UNO includes === **/
+
+#include <cppuhelper/implbase1.hxx>
+
+#include <memory>
+#include <map>
+#include <boost/noncopyable.hpp>
+
+namespace dbaccess
+{
+
+ typedef ::std::map< ::rtl::OUString, ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > >
+ DocumentEventsData;
+
+ //====================================================================
+ //= DocumentEvents
+ //====================================================================
+ struct DocumentEvents_Data;
+
+ typedef ::cppu::WeakImplHelper1 < ::com::sun::star::container::XNameReplace
+ > DocumentEvents_Base;
+
+ class DocumentEvents :public DocumentEvents_Base
+ ,public ::boost::noncopyable
+ {
+ public:
+ DocumentEvents( ::cppu::OWeakObject& _rParent, ::osl::Mutex& _rMutex, DocumentEventsData& _rEventsData );
+ ~DocumentEvents();
+
+ static bool needsSynchronousNotification( const ::rtl::OUString& _rEventName );
+
+ // XInterface
+ virtual void SAL_CALL acquire() throw();
+ virtual void SAL_CALL release() throw();
+
+ // XNameReplace
+ virtual void SAL_CALL replaceByName( const ::rtl::OUString& aName, const ::com::sun::star::uno::Any& aElement ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+ // XNameAccess
+ virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XElementAccess
+ virtual ::com::sun::star::uno::Type SAL_CALL getElementType( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL hasElements( ) throw (::com::sun::star::uno::RuntimeException);
+
+ private:
+ ::std::auto_ptr< DocumentEvents_Data > m_pData;
+ };
+
+} // namespace dbaccess
+
+#endif // DBACCESS_DOCUMENTEVENTS_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/intercept.cxx b/dbaccess/source/core/dataaccess/intercept.cxx
new file mode 100644
index 000000000000..1b950f2851be
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/intercept.cxx
@@ -0,0 +1,446 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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"
+
+#include "intercept.hxx"
+#include "dbastrings.hrc"
+
+#include <com/sun/star/embed/EmbedStates.hpp>
+#include <com/sun/star/document/XEventBroadcaster.hpp>
+#include <com/sun/star/util/XModifiable.hpp>
+#include <cppuhelper/weak.hxx>
+
+#include <comphelper/types.hxx>
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+
+
+namespace dbaccess
+{
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::embed;
+using namespace ::com::sun::star::container;
+using namespace ::comphelper;
+using namespace ::cppu;
+
+#define DISPATCH_SAVEAS 0
+#define DISPATCH_SAVE 1
+#define DISPATCH_CLOSEDOC 2
+#define DISPATCH_CLOSEWIN 3
+#define DISPATCH_CLOSEFRAME 4
+#define DISPATCH_RELOAD 5
+// the OSL_ENSURE in CTOR has to be changed too, when adding new defines
+
+void SAL_CALL OInterceptor::dispose()
+ throw( RuntimeException )
+{
+ EventObject aEvt( *this );
+
+ osl::MutexGuard aGuard(m_aMutex);
+
+ if ( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() )
+ m_pDisposeEventListeners->disposeAndClear( aEvt );
+
+ if ( m_pStatCL )
+ m_pStatCL->disposeAndClear( aEvt );
+
+ m_xSlaveDispatchProvider.clear();
+ m_xMasterDispatchProvider.clear();
+
+ m_pContentHolder = NULL;
+}
+
+
+DBG_NAME(OInterceptor)
+
+OInterceptor::OInterceptor( ODocumentDefinition* _pContentHolder,sal_Bool _bAllowEditDoc )
+ :m_pContentHolder( _pContentHolder )
+ ,m_aInterceptedURL(7)
+ ,m_pDisposeEventListeners(0)
+ ,m_pStatCL(0)
+ ,m_bAllowEditDoc(_bAllowEditDoc)
+{
+ DBG_CTOR(OInterceptor,NULL);
+
+ OSL_ENSURE(DISPATCH_RELOAD < m_aInterceptedURL.getLength(),"Illegal size.");
+
+ m_aInterceptedURL[DISPATCH_SAVEAS] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:SaveAs"));
+ m_aInterceptedURL[DISPATCH_SAVE] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:Save"));
+ m_aInterceptedURL[DISPATCH_CLOSEDOC] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:CloseDoc"));
+ m_aInterceptedURL[DISPATCH_CLOSEWIN] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:CloseWin"));
+ m_aInterceptedURL[DISPATCH_CLOSEFRAME] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:CloseFrame"));
+ m_aInterceptedURL[DISPATCH_RELOAD] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:Reload"));
+}
+
+
+OInterceptor::~OInterceptor()
+{
+ if( m_pDisposeEventListeners )
+ delete m_pDisposeEventListeners;
+
+ if(m_pStatCL)
+ delete m_pStatCL;
+
+ DBG_DTOR(OInterceptor,NULL);
+}
+
+struct DispatchHelper
+{
+ URL aURL;
+ Sequence<PropertyValue > aArguments;
+};
+
+//XDispatch
+void SAL_CALL OInterceptor::dispatch( const URL& _URL,const Sequence<PropertyValue >& Arguments ) throw (RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( !m_pContentHolder )
+ return;
+
+ if ( _URL.Complete == m_aInterceptedURL[ DISPATCH_SAVE ] )
+ {
+ m_pContentHolder->save( sal_False );
+ return;
+ }
+
+ if ( _URL.Complete == m_aInterceptedURL[ DISPATCH_RELOAD ] )
+ {
+ ODocumentDefinition::fillReportData(
+ m_pContentHolder->getContext(),
+ m_pContentHolder->getComponent(),
+ m_pContentHolder->getConnection()
+ );
+ return;
+ }
+
+ if( _URL.Complete == m_aInterceptedURL[ DISPATCH_SAVEAS ] )
+ {
+ if ( m_pContentHolder->isNewReport() )
+ {
+ m_pContentHolder->saveAs();
+ }
+ else if ( m_xSlaveDispatchProvider.is() )
+ {
+ Sequence< PropertyValue > aNewArgs = Arguments;
+ sal_Int32 nInd = 0;
+
+ while( nInd < aNewArgs.getLength() )
+ {
+ if ( aNewArgs[nInd].Name.equalsAscii( "SaveTo" ) )
+ {
+ aNewArgs[nInd].Value <<= sal_True;
+ break;
+ }
+ nInd++;
+ }
+
+ if ( nInd == aNewArgs.getLength() )
+ {
+ aNewArgs.realloc( nInd + 1 );
+ aNewArgs[nInd].Name = ::rtl::OUString::createFromAscii( "SaveTo" );
+ aNewArgs[nInd].Value <<= sal_True;
+ }
+
+ Reference< XDispatch > xDispatch = m_xSlaveDispatchProvider->queryDispatch(
+ _URL, ::rtl::OUString::createFromAscii( "_self" ), 0 );
+ if ( xDispatch.is() )
+ xDispatch->dispatch( _URL, aNewArgs );
+ }
+ return;
+ }
+
+ if ( _URL.Complete == m_aInterceptedURL[ DISPATCH_CLOSEDOC ]
+ || _URL.Complete == m_aInterceptedURL[ DISPATCH_CLOSEWIN ]
+ || _URL.Complete == m_aInterceptedURL[ DISPATCH_CLOSEFRAME ]
+ )
+ {
+ DispatchHelper* pHelper = new DispatchHelper;
+ pHelper->aArguments = Arguments;
+ pHelper->aURL = _URL;
+ Application::PostUserEvent( LINK( this, OInterceptor, OnDispatch ), reinterpret_cast< void* >( pHelper ) );
+ return;
+ }
+}
+
+IMPL_LINK( OInterceptor, OnDispatch, void*, _pDispatcher )
+{
+ ::std::auto_ptr<DispatchHelper> pHelper( reinterpret_cast< DispatchHelper* >( _pDispatcher ) );
+ try
+ {
+ if ( m_pContentHolder && m_pContentHolder->prepareClose() && m_xSlaveDispatchProvider.is() )
+ {
+ Reference< XDispatch > xDispatch = m_xSlaveDispatchProvider->queryDispatch(
+ pHelper->aURL, ::rtl::OUString::createFromAscii( "_self" ), 0 );
+ if ( xDispatch.is() )
+ {
+ Reference< ::com::sun::star::document::XEventBroadcaster> xEvtB(m_pContentHolder->getComponent(),UNO_QUERY);
+ if ( xEvtB.is() )
+ xEvtB->removeEventListener(this);
+
+ Reference< XInterface > xKeepContentHolderAlive( *m_pContentHolder );
+ xDispatch->dispatch( pHelper->aURL,pHelper->aArguments);
+ }
+ }
+ }
+ catch ( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ return 0L;
+}
+
+void SAL_CALL OInterceptor::addStatusListener(
+ const Reference<
+ XStatusListener >& Control,
+ const URL& _URL )
+ throw (
+ RuntimeException
+ )
+{
+ if(!Control.is())
+ return;
+
+ if ( m_pContentHolder && _URL.Complete == m_aInterceptedURL[DISPATCH_SAVEAS] )
+ { // SaveAs
+
+ if ( !m_pContentHolder->isNewReport() )
+ {
+ FeatureStateEvent aStateEvent;
+ aStateEvent.FeatureURL.Complete = m_aInterceptedURL[DISPATCH_SAVEAS];
+ aStateEvent.FeatureDescriptor = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SaveCopyTo"));
+ aStateEvent.IsEnabled = sal_True;
+ aStateEvent.Requery = sal_False;
+ aStateEvent.State <<= (rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("($3)")));
+ Control->statusChanged(aStateEvent);
+ }
+
+ {
+ osl::MutexGuard aGuard(m_aMutex);
+ if(!m_pStatCL)
+ m_pStatCL = new PropertyChangeListenerContainer(m_aMutex);
+ }
+
+ m_pStatCL->addInterface(_URL.Complete,Control);
+ }
+ else if ( m_pContentHolder && _URL.Complete == m_aInterceptedURL[DISPATCH_SAVE] )
+ { // Save
+ FeatureStateEvent aStateEvent;
+ aStateEvent.FeatureURL.Complete = m_aInterceptedURL[DISPATCH_SAVE];
+ aStateEvent.FeatureDescriptor = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Update"));
+ aStateEvent.IsEnabled = m_pContentHolder != NULL && m_pContentHolder->isModified();
+ aStateEvent.Requery = sal_False;
+
+ Control->statusChanged(aStateEvent);
+ {
+ osl::MutexGuard aGuard(m_aMutex);
+ if(!m_pStatCL)
+ m_pStatCL = new PropertyChangeListenerContainer(m_aMutex);
+ }
+
+ m_pStatCL->addInterface(_URL.Complete,Control);
+ Reference< ::com::sun::star::document::XEventBroadcaster> xEvtB(m_pContentHolder->getComponent(),UNO_QUERY);
+ if ( xEvtB.is() )
+ xEvtB->addEventListener(this);
+ }
+ else
+ {
+ sal_Int32 i = 2;
+ if(_URL.Complete == m_aInterceptedURL[i] ||
+ _URL.Complete == m_aInterceptedURL[++i] ||
+ _URL.Complete == m_aInterceptedURL[++i] ||
+ _URL.Complete == m_aInterceptedURL[i = DISPATCH_RELOAD] )
+ { // Close and return
+ FeatureStateEvent aStateEvent;
+ aStateEvent.FeatureURL.Complete = m_aInterceptedURL[i];
+ aStateEvent.FeatureDescriptor = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("Close and Return"));
+ aStateEvent.IsEnabled = sal_True;
+ aStateEvent.Requery = sal_False;
+ Control->statusChanged(aStateEvent);
+
+
+ {
+ osl::MutexGuard aGuard(m_aMutex);
+ if(!m_pStatCL)
+ m_pStatCL = new PropertyChangeListenerContainer(m_aMutex);
+ }
+
+ m_pStatCL->addInterface(_URL.Complete,Control);
+ return;
+ }
+ }
+}
+
+
+void SAL_CALL OInterceptor::removeStatusListener(
+ const Reference<
+ XStatusListener >& Control,
+ const URL& _URL )
+ throw (
+ RuntimeException
+ )
+{
+ if(!(Control.is() && m_pStatCL))
+ return;
+ else
+ {
+ m_pStatCL->removeInterface(_URL.Complete,Control);
+ return;
+ }
+}
+
+
+//XInterceptorInfo
+Sequence< ::rtl::OUString > SAL_CALL OInterceptor::getInterceptedURLs( ) throw ( RuntimeException )
+{
+ // now implemented as update
+ return m_aInterceptedURL;
+}
+
+
+// XDispatchProvider
+
+Reference< XDispatch > SAL_CALL OInterceptor::queryDispatch( const URL& _URL,const ::rtl::OUString& TargetFrameName,sal_Int32 SearchFlags )
+ throw (RuntimeException)
+{
+ osl::MutexGuard aGuard(m_aMutex);
+ const ::rtl::OUString* pIter = m_aInterceptedURL.getConstArray();
+ const ::rtl::OUString* pEnd = pIter + m_aInterceptedURL.getLength();
+ for(;pIter != pEnd;++pIter)
+ {
+ if ( _URL.Complete == *pIter )
+ return (XDispatch*)this;
+ }
+
+ if(m_xSlaveDispatchProvider.is())
+ return m_xSlaveDispatchProvider->queryDispatch(_URL,TargetFrameName,SearchFlags);
+ else
+ return Reference<XDispatch>();
+}
+
+Sequence< Reference< XDispatch > > SAL_CALL OInterceptor::queryDispatches( const Sequence<DispatchDescriptor >& Requests ) throw ( RuntimeException )
+{
+ Sequence< Reference< XDispatch > > aRet;
+ osl::MutexGuard aGuard(m_aMutex);
+ if(m_xSlaveDispatchProvider.is())
+ aRet = m_xSlaveDispatchProvider->queryDispatches(Requests);
+ else
+ aRet.realloc(Requests.getLength());
+
+ for(sal_Int32 i = 0; i < Requests.getLength(); ++i)
+ {
+ const ::rtl::OUString* pIter = m_aInterceptedURL.getConstArray();
+ const ::rtl::OUString* pEnd = pIter + m_aInterceptedURL.getLength();
+ for(;pIter != pEnd;++pIter)
+ {
+ if ( Requests[i].FeatureURL.Complete == *pIter )
+ {
+ aRet[i] = (XDispatch*) this;
+ break;
+ }
+ }
+ }
+
+ return aRet;
+}
+
+
+
+//XDispatchProviderInterceptor
+
+Reference< XDispatchProvider > SAL_CALL OInterceptor::getSlaveDispatchProvider( ) throw ( RuntimeException )
+{
+ osl::MutexGuard aGuard(m_aMutex);
+ return m_xSlaveDispatchProvider;
+}
+
+void SAL_CALL
+OInterceptor::setSlaveDispatchProvider( const Reference< XDispatchProvider >& NewDispatchProvider )
+ throw ( RuntimeException )
+{
+ osl::MutexGuard aGuard(m_aMutex);
+ m_xSlaveDispatchProvider = NewDispatchProvider;
+}
+
+
+Reference< XDispatchProvider > SAL_CALL OInterceptor::getMasterDispatchProvider( )
+ throw (
+ RuntimeException
+ )
+{
+ osl::MutexGuard aGuard(m_aMutex);
+ return m_xMasterDispatchProvider;
+}
+
+
+void SAL_CALL OInterceptor::setMasterDispatchProvider(
+ const Reference< XDispatchProvider >& NewSupplier )
+ throw (
+ RuntimeException
+ )
+{
+ osl::MutexGuard aGuard(m_aMutex);
+ m_xMasterDispatchProvider = NewSupplier;
+}
+
+void SAL_CALL OInterceptor::notifyEvent( const ::com::sun::star::document::EventObject& Event ) throw (::com::sun::star::uno::RuntimeException)
+{
+ osl::ResettableMutexGuard _rGuard(m_aMutex);
+ if ( m_pStatCL && Event.EventName == ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OnModifyChanged")) )
+ {
+ OInterfaceContainerHelper* pListener = m_pStatCL->getContainer(m_aInterceptedURL[DISPATCH_SAVE]);
+ if ( pListener )
+ {
+ FeatureStateEvent aEvt;
+ aEvt.FeatureURL.Complete = m_aInterceptedURL[DISPATCH_SAVE];
+ aEvt.FeatureDescriptor = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Update"));
+ Reference<XModifiable> xModel(Event.Source,UNO_QUERY);
+ aEvt.IsEnabled = xModel.is() && xModel->isModified();
+ aEvt.Requery = sal_False;
+
+ NOTIFY_LISTERNERS((*pListener),XStatusListener,statusChanged)
+ }
+ }
+}
+
+void SAL_CALL OInterceptor::disposing( const ::com::sun::star::lang::EventObject& /*Source*/ ) throw (::com::sun::star::uno::RuntimeException)
+{
+}
+
+} // namespace dbaccess
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/intercept.hxx b/dbaccess/source/core/dataaccess/intercept.hxx
new file mode 100644
index 000000000000..cb2cadc77c07
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/intercept.hxx
@@ -0,0 +1,169 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef DBA_INTERCEPT_HXX
+#define DBA_INTERCEPT_HXX
+
+#include <osl/mutex.hxx>
+#include <cppuhelper/implbase4.hxx>
+#include <cppuhelper/interfacecontainer.hxx>
+#include <com/sun/star/frame/XDispatchProviderInterceptor.hpp>
+#include <com/sun/star/frame/XInterceptorInfo.hpp>
+#include <com/sun/star/document/XEventListener.hpp>
+#include <com/sun/star/frame/XDispatch.hpp>
+#include "documentdefinition.hxx"
+#include <vcl/svapp.hxx>
+
+namespace dbaccess
+{
+
+
+class OInterceptor : public ::cppu::WeakImplHelper4< ::com::sun::star::frame::XDispatchProviderInterceptor,
+ ::com::sun::star::frame::XInterceptorInfo,
+ ::com::sun::star::frame::XDispatch,
+ ::com::sun::star::document::XEventListener>
+{
+ DECL_LINK( OnDispatch, void* _aURL );
+protected:
+ virtual ~OInterceptor();
+public:
+
+ OInterceptor( ODocumentDefinition* _pContentHolder,sal_Bool _bAllowEditDoc );
+
+ void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException);
+
+ //XDispatch
+ virtual void SAL_CALL
+ dispatch(
+ const ::com::sun::star::util::URL& URL,
+ const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::beans::PropertyValue >& Arguments )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addStatusListener(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::frame::XStatusListener >& Control,
+ const ::com::sun::star::util::URL& URL )
+ throw (
+ ::com::sun::star::uno::RuntimeException
+ );
+
+ virtual void SAL_CALL
+ removeStatusListener(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::frame::XStatusListener >& Control,
+ const ::com::sun::star::util::URL& URL )
+ throw (
+ ::com::sun::star::uno::RuntimeException
+ );
+
+ //XInterceptorInfo
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString >
+ SAL_CALL getInterceptedURLs( )
+ throw (
+ ::com::sun::star::uno::RuntimeException
+ );
+
+ //XDispatchProvider ( inherited by XDispatchProviderInterceptor )
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::frame::XDispatch > SAL_CALL
+ queryDispatch(
+ const ::com::sun::star::util::URL& URL,
+ const ::rtl::OUString& TargetFrameName,
+ sal_Int32 SearchFlags )
+ throw (
+ ::com::sun::star::uno::RuntimeException
+ );
+
+ virtual ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::frame::XDispatch > > SAL_CALL
+ queryDispatches(
+ const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::frame::DispatchDescriptor >& Requests )
+ throw (
+ ::com::sun::star::uno::RuntimeException
+ );
+
+ //XDispatchProviderInterceptor
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::frame::XDispatchProvider > SAL_CALL
+ getSlaveDispatchProvider( )
+ throw (
+ ::com::sun::star::uno::RuntimeException
+ );
+
+ virtual void SAL_CALL
+ setSlaveDispatchProvider(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::frame::XDispatchProvider >& NewDispatchProvider )
+ throw (
+ ::com::sun::star::uno::RuntimeException
+ );
+
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::frame::XDispatchProvider > SAL_CALL
+ getMasterDispatchProvider( )
+ throw (
+ ::com::sun::star::uno::RuntimeException
+ );
+
+ virtual void SAL_CALL
+ setMasterDispatchProvider(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::frame::XDispatchProvider >& NewSupplier )
+ throw (
+ ::com::sun::star::uno::RuntimeException
+ );
+
+ // XEventListener
+ virtual void SAL_CALL notifyEvent( const ::com::sun::star::document::EventObject& Event ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);
+
+private:
+
+ osl::Mutex m_aMutex;
+
+ ODocumentDefinition* m_pContentHolder;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider > m_xSlaveDispatchProvider;
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider > m_xMasterDispatchProvider;
+
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > m_aInterceptedURL;
+
+ cppu::OInterfaceContainerHelper* m_pDisposeEventListeners;
+ PropertyChangeListenerContainer* m_pStatCL;
+ sal_Bool m_bAllowEditDoc;
+};
+
+} // namespace dbaccess
+
+#endif //DBA_INTERCEPT_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/makefile.mk b/dbaccess/source/core/dataaccess/makefile.mk
new file mode 100644
index 000000000000..e37544b70bf7
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/makefile.mk
@@ -0,0 +1,69 @@
+#*************************************************************************
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+PRJINC=$(PRJ)$/source
+PRJNAME=dbaccess
+TARGET=dataaccess
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings ----------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/dba.pmk
+
+# --- Files -------------------------------------
+
+SLOFILES= \
+ $(SLO)$/SharedConnection.obj \
+ $(SLO)$/ContentHelper.obj \
+ $(SLO)$/bookmarkcontainer.obj \
+ $(SLO)$/definitioncontainer.obj \
+ $(SLO)$/commanddefinition.obj \
+ $(SLO)$/documentcontainer.obj \
+ $(SLO)$/commandcontainer.obj \
+ $(SLO)$/documentdefinition.obj \
+ $(SLO)$/ComponentDefinition.obj \
+ $(SLO)$/databasecontext.obj \
+ $(SLO)$/connection.obj \
+ $(SLO)$/datasource.obj \
+ $(SLO)$/databaseregistrations.obj \
+ $(SLO)$/intercept.obj \
+ $(SLO)$/myucp_datasupplier.obj \
+ $(SLO)$/myucp_resultset.obj \
+ $(SLO)$/databasedocument.obj \
+ $(SLO)$/dataaccessdescriptor.obj\
+ $(SLO)$/ModelImpl.obj \
+ $(SLO)$/documentevents.obj \
+ $(SLO)$/documenteventexecutor.obj \
+ $(SLO)$/documenteventnotifier.obj \
+
+# --- Targets ----------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/dbaccess/source/core/dataaccess/myucp_datasupplier.cxx b/dbaccess/source/core/dataaccess/myucp_datasupplier.cxx
new file mode 100644
index 000000000000..93177d05b5fd
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/myucp_datasupplier.cxx
@@ -0,0 +1,393 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+
+#include <vector>
+
+#include <ucbhelper/contentidentifier.hxx>
+#include <ucbhelper/providerhelper.hxx>
+
+#include "myucp_datasupplier.hxx"
+#include "ContentHelper.hxx"
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <tools/debug.hxx>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::container;
+
+// @@@ Adjust namespace name.
+using namespace dbaccess;
+
+// @@@ Adjust namespace name.
+namespace dbaccess
+{
+
+//=========================================================================
+//
+// struct ResultListEntry.
+//
+//=========================================================================
+
+struct ResultListEntry
+{
+ rtl::OUString aId;
+ Reference< XContentIdentifier > xId;
+ ::rtl::Reference< OContentHelper > xContent;
+ Reference< XRow > xRow;
+ const ContentProperties& rData;
+
+ ResultListEntry( const ContentProperties& rEntry ) : rData( rEntry ) {}
+};
+
+//=========================================================================
+//
+// ResultList.
+//
+//=========================================================================
+
+typedef std::vector< ResultListEntry* > ResultList;
+
+//=========================================================================
+//
+// struct DataSupplier_Impl.
+//
+//=========================================================================
+
+struct DataSupplier_Impl
+{
+ osl::Mutex m_aMutex;
+ ResultList m_aResults;
+ rtl::Reference< ODocumentContainer > m_xContent;
+ Reference< XMultiServiceFactory > m_xSMgr;
+ sal_Int32 m_nOpenMode;
+ sal_Bool m_bCountFinal;
+
+ DataSupplier_Impl( const Reference< XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< ODocumentContainer >& rContent,
+ sal_Int32 nOpenMode )
+ : m_xContent(rContent)
+ , m_xSMgr( rxSMgr )
+ , m_nOpenMode( nOpenMode )
+ , m_bCountFinal( sal_False ) {}
+ ~DataSupplier_Impl();
+};
+
+//=========================================================================
+DataSupplier_Impl::~DataSupplier_Impl()
+{
+ ResultList::const_iterator it = m_aResults.begin();
+ ResultList::const_iterator end = m_aResults.end();
+
+ while ( it != end )
+ {
+ delete (*it);
+ it++;
+ }
+}
+
+}
+
+//=========================================================================
+//
+// DataSupplier Implementation.
+//
+//=========================================================================
+DBG_NAME(DataSupplier)
+
+DataSupplier::DataSupplier( const Reference< XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< ODocumentContainer >& rContent,
+ sal_Int32 nOpenMode )
+: m_pImpl( new DataSupplier_Impl( rxSMgr, rContent,nOpenMode ) )
+{
+ DBG_CTOR(DataSupplier,NULL);
+
+}
+
+DataSupplier::~DataSupplier()
+{
+
+ DBG_DTOR(DataSupplier,NULL);
+}
+
+rtl::OUString DataSupplier::queryContentIdentifierString( sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( (size_t)nIndex < m_pImpl->m_aResults.size() )
+ {
+ rtl::OUString aId = m_pImpl->m_aResults[ nIndex ]->aId;
+ if ( aId.getLength() )
+ {
+ // Already cached.
+ return aId;
+ }
+ }
+
+ if ( getResult( nIndex ) )
+ {
+ rtl::OUString aId
+ = m_pImpl->m_xContent->getIdentifier()->getContentIdentifier();
+
+ if ( aId.getLength() )
+ aId += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"));
+
+ aId += m_pImpl->m_aResults[ nIndex ]->rData.aTitle;
+
+ m_pImpl->m_aResults[ nIndex ]->aId = aId;
+ return aId;
+ }
+ return rtl::OUString();
+}
+
+Reference< XContentIdentifier >
+DataSupplier::queryContentIdentifier( sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( (size_t)nIndex < m_pImpl->m_aResults.size() )
+ {
+ Reference< XContentIdentifier > xId = m_pImpl->m_aResults[ nIndex ]->xId;
+ if ( xId.is() )
+ {
+ // Already cached.
+ return xId;
+ }
+ }
+
+ rtl::OUString aId = queryContentIdentifierString( nIndex );
+ if ( aId.getLength() )
+ {
+ Reference< XContentIdentifier > xId = new ::ucbhelper::ContentIdentifier( aId );
+ m_pImpl->m_aResults[ nIndex ]->xId = xId;
+ return xId;
+ }
+ return Reference< XContentIdentifier >();
+}
+
+Reference< XContent >
+DataSupplier::queryContent( sal_uInt32 _nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( (size_t)_nIndex < m_pImpl->m_aResults.size() )
+ {
+ Reference< XContent > xContent = m_pImpl->m_aResults[ _nIndex ]->xContent.get();
+ if ( xContent.is() )
+ {
+ // Already cached.
+ return xContent;
+ }
+ }
+
+ Reference< XContentIdentifier > xId = queryContentIdentifier( _nIndex );
+ if ( xId.is() )
+ {
+ try
+ {
+ Reference< XContent > xContent;
+ ::rtl::OUString sName = xId->getContentIdentifier();
+ sal_Int32 nIndex = sName.lastIndexOf('/') + 1;
+ sName = sName.getToken(0,'/',nIndex);
+
+ m_pImpl->m_aResults[ _nIndex ]->xContent = m_pImpl->m_xContent->getContent(sName);
+
+ xContent = m_pImpl->m_aResults[ _nIndex ]->xContent.get();
+ return xContent;
+
+ }
+ catch ( IllegalIdentifierException& )
+ {
+ }
+ }
+ return Reference< XContent >();
+}
+
+sal_Bool DataSupplier::getResult( sal_uInt32 nIndex )
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( (size_t)nIndex < m_pImpl->m_aResults.size() )
+ {
+ // Result already present.
+ return sal_True;
+ }
+
+ // Result not (yet) present.
+
+ if ( m_pImpl->m_bCountFinal )
+ return sal_False;
+
+ // Try to obtain result...
+
+ sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
+ sal_Bool bFound = sal_False;
+ sal_uInt32 nPos = nOldCount;
+
+ // @@@ Obtain data and put it into result list...
+ Sequence< ::rtl::OUString> aSeq = m_pImpl->m_xContent->getElementNames();
+ if ( nIndex < sal::static_int_cast< sal_uInt32 >( aSeq.getLength() ) )
+ {
+ const ::rtl::OUString* pIter = aSeq.getConstArray();
+ const ::rtl::OUString* pEnd = pIter + aSeq.getLength();
+ for(pIter = pIter + nPos;pIter != pEnd;++pIter,++nPos)
+ {
+ m_pImpl->m_aResults.push_back(
+ new ResultListEntry( m_pImpl->m_xContent->getContent(*pIter)->getContentProperties() ) );
+
+ if ( nPos == nIndex )
+ {
+ // Result obtained.
+ bFound = sal_True;
+ break;
+ }
+ }
+ }
+
+ if ( !bFound )
+ m_pImpl->m_bCountFinal = sal_True;
+
+ rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
+ if ( xResultSet.is() )
+ {
+ // Callbacks follow!
+ aGuard.clear();
+
+ if ( (size_t)nOldCount < m_pImpl->m_aResults.size() )
+ xResultSet->rowCountChanged(
+ nOldCount, m_pImpl->m_aResults.size() );
+
+ if ( m_pImpl->m_bCountFinal )
+ xResultSet->rowCountFinal();
+ }
+
+ return bFound;
+}
+
+sal_uInt32 DataSupplier::totalCount()
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( m_pImpl->m_bCountFinal )
+ return m_pImpl->m_aResults.size();
+
+ sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
+
+ // @@@ Obtain data and put it into result list...
+ Sequence< ::rtl::OUString> aSeq = m_pImpl->m_xContent->getElementNames();
+ const ::rtl::OUString* pIter = aSeq.getConstArray();
+ const ::rtl::OUString* pEnd = pIter + aSeq.getLength();
+ for(;pIter != pEnd;++pIter)
+ m_pImpl->m_aResults.push_back(
+ new ResultListEntry( m_pImpl->m_xContent->getContent(*pIter)->getContentProperties() ) );
+
+ m_pImpl->m_bCountFinal = sal_True;
+
+ rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
+ if ( xResultSet.is() )
+ {
+ // Callbacks follow!
+ aGuard.clear();
+
+ if ( (size_t)nOldCount < m_pImpl->m_aResults.size() )
+ xResultSet->rowCountChanged(
+ nOldCount, m_pImpl->m_aResults.size() );
+
+ xResultSet->rowCountFinal();
+ }
+
+ return m_pImpl->m_aResults.size();
+}
+
+sal_uInt32 DataSupplier::currentCount()
+{
+ return m_pImpl->m_aResults.size();
+}
+
+sal_Bool DataSupplier::isCountFinal()
+{
+ return m_pImpl->m_bCountFinal;
+}
+
+Reference< XRow >
+DataSupplier::queryPropertyValues( sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( (size_t)nIndex < m_pImpl->m_aResults.size() )
+ {
+ Reference< XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xRow;
+ if ( xRow.is() )
+ {
+ // Already cached.
+ return xRow;
+ }
+ }
+
+ if ( getResult( nIndex ) )
+ {
+ if ( !m_pImpl->m_aResults[ nIndex ]->xContent.is() )
+ queryContent(nIndex);
+
+ Reference< XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xContent->getPropertyValues(getResultSet()->getProperties());
+ m_pImpl->m_aResults[ nIndex ]->xRow = xRow;
+ return xRow;
+ }
+
+ return Reference< XRow >();
+}
+
+void DataSupplier::releasePropertyValues( sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( (size_t)nIndex < m_pImpl->m_aResults.size() )
+ m_pImpl->m_aResults[ nIndex ]->xRow = Reference< XRow >();
+}
+
+void DataSupplier::close()
+{
+}
+
+void DataSupplier::validate()
+ throw( ResultSetException )
+{
+}
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/myucp_datasupplier.hxx b/dbaccess/source/core/dataaccess/myucp_datasupplier.hxx
new file mode 100644
index 000000000000..77dcbf2e9659
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/myucp_datasupplier.hxx
@@ -0,0 +1,80 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef DBA_DATASUPPLIER_HXX
+#define DBA_DATASUPPLIER_HXX
+
+#include <rtl/ref.hxx>
+#include <ucbhelper/resultset.hxx>
+#include "documentcontainer.hxx"
+#include <memory>
+
+namespace dbaccess {
+
+struct DataSupplier_Impl;
+class OContentHelper;
+
+class DataSupplier : public ucbhelper::ResultSetDataSupplier
+{
+ ::std::auto_ptr<DataSupplier_Impl> m_pImpl;
+
+public:
+ DataSupplier( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< ODocumentContainer >& rxContent,
+ sal_Int32 nOpenMode );
+ virtual ~DataSupplier();
+
+ virtual rtl::OUString queryContentIdentifierString( sal_uInt32 nIndex );
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >
+ queryContentIdentifier( sal_uInt32 nIndex );
+ virtual com::sun::star::uno::Reference< com::sun::star::ucb::XContent >
+ queryContent( sal_uInt32 nIndex );
+
+ virtual sal_Bool getResult( sal_uInt32 nIndex );
+
+ virtual sal_uInt32 totalCount();
+ virtual sal_uInt32 currentCount();
+ virtual sal_Bool isCountFinal();
+
+ virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XRow >
+ queryPropertyValues( sal_uInt32 nIndex );
+ virtual void releasePropertyValues( sal_uInt32 nIndex );
+
+ virtual void close();
+
+ virtual void validate()
+ throw( com::sun::star::ucb::ResultSetException );
+};
+
+}
+
+#endif // DBA_DATASUPPLIER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/myucp_resultset.cxx b/dbaccess/source/core/dataaccess/myucp_resultset.cxx
new file mode 100644
index 000000000000..d59336d87527
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/myucp_resultset.cxx
@@ -0,0 +1,99 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ - This implementation is not a dynamic result set!!! It only implements
+ the necessary interfaces, but never recognizes/notifies changes!!!
+
+ *************************************************************************/
+
+#include "myucp_datasupplier.hxx"
+#include "myucp_resultset.hxx"
+
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::container;
+
+using namespace dbaccess;
+
+//=========================================================================
+//
+// DynamicResultSet Implementation.
+//
+//=========================================================================
+
+DynamicResultSet::DynamicResultSet(
+ const Reference< XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< ODocumentContainer >& rxContent,
+ const OpenCommandArgument2& rCommand,
+ const Reference< XCommandEnvironment >& rxEnv )
+ :ResultSetImplHelper( rxSMgr, rCommand )
+ ,m_xContent(rxContent)
+ ,m_xEnv( rxEnv )
+{
+}
+
+//=========================================================================
+//
+// Non-interface methods.
+//
+//=========================================================================
+void DynamicResultSet::initStatic()
+{
+ m_xResultSet1
+ = new ::ucbhelper::ResultSet( m_xSMgr,
+ m_aCommand.Properties,
+ new DataSupplier( m_xSMgr,
+ m_xContent,
+ m_aCommand.Mode ),
+ m_xEnv );
+}
+
+void DynamicResultSet::initDynamic()
+{
+ m_xResultSet1
+ = new ::ucbhelper::ResultSet( m_xSMgr,
+ m_aCommand.Properties,
+ new DataSupplier( m_xSMgr,
+ m_xContent,
+ m_aCommand.Mode ),
+ m_xEnv );
+ m_xResultSet2 = m_xResultSet1;
+}
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/core/dataaccess/myucp_resultset.hxx b/dbaccess/source/core/dataaccess/myucp_resultset.hxx
new file mode 100644
index 000000000000..b74be38df9d6
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/myucp_resultset.hxx
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef DBA_UCPRESULTSET_HXX
+#define DBA_UCPRESULTSET_HXX
+
+#include <rtl/ref.hxx>
+#include <ucbhelper/resultsethelper.hxx>
+#include "documentcontainer.hxx"
+
+
+// @@@ Adjust namespace name.
+namespace dbaccess {
+
+class DynamicResultSet : public ::ucbhelper::ResultSetImplHelper
+{
+ rtl::Reference< ODocumentContainer > m_xContent;
+ com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > m_xEnv;
+
+private:
+ virtual void initStatic();
+ virtual void initDynamic();
+
+public:
+ DynamicResultSet(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< ODocumentContainer >& rxContent,
+ const com::sun::star::ucb::OpenCommandArgument2& rCommand,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& rxEnv );
+};
+
+}
+
+#endif // DBA_UCPRESULTSET_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */