diff options
author | Frank Schoenheit [fs] <frank.schoenheit@sun.com> | 2009-11-04 14:40:44 +0100 |
---|---|---|
committer | Frank Schoenheit [fs] <frank.schoenheit@sun.com> | 2009-11-04 14:40:44 +0100 |
commit | 7c5b2130b651f7417f1c16457b132f9d7d043422 (patch) | |
tree | 412279da75e420dc49926a7450a2e5dc2ce2dd42 /dbaccess | |
parent | 73b50374f96e91248bee76b8fbda3b4dc59ce016 (diff) |
a little less deadlock-prone ...
Diffstat (limited to 'dbaccess')
-rw-r--r-- | dbaccess/source/core/dataaccess/documentcontainer.cxx | 84 | ||||
-rw-r--r-- | dbaccess/source/core/dataaccess/documentdefinition.cxx | 361 | ||||
-rw-r--r-- | dbaccess/source/core/dataaccess/documentdefinition.hxx | 34 | ||||
-rw-r--r-- | dbaccess/source/core/dataaccess/intercept.cxx | 130 | ||||
-rw-r--r-- | dbaccess/source/core/inc/ContentHelper.hxx | 2 |
5 files changed, 304 insertions, 307 deletions
diff --git a/dbaccess/source/core/dataaccess/documentcontainer.cxx b/dbaccess/source/core/dataaccess/documentcontainer.cxx index c5b176478ecd..96cae44e6a3e 100644 --- a/dbaccess/source/core/dataaccess/documentcontainer.cxx +++ b/dbaccess/source/core/dataaccess/documentcontainer.cxx @@ -88,6 +88,7 @@ #include <vcl/svapp.hxx> #include <vos/mutex.hxx> +#include <comphelper/namedvaluecollection.hxx> using namespace ::com::sun::star::uno; using namespace ::com::sun::star::lang; @@ -212,60 +213,32 @@ Reference< XInterface > SAL_CALL ODocumentContainer::createInstanceWithArguments if ( ServiceSpecifier == SERVICE_SDB_DOCUMENTDEFINITION ) { MutexGuard aGuard(m_aMutex); - ::rtl::OUString sName,sPersistentName,sURL; + + ::rtl::OUString sName, sPersistentName, sURL, sMediaType; Reference< XCommandProcessor > xCopyFrom; - Reference<XConnection> xConnection; - Sequence<sal_Int8> aClassID; + Reference< XConnection > xConnection; + Sequence< sal_Int8 > aClassID; sal_Bool bAsTemplate = sal_False; - const Any* pBegin = _aArguments.getConstArray(); - const Any* pEnd = pBegin + _aArguments.getLength(); - PropertyValue aValue; - for(;pBegin != pEnd;++pBegin) - { - *pBegin >>= aValue; - if ( aValue.Name.equalsAscii(PROPERTY_NAME) ) - { - aValue.Value >>= sName; - } - else if ( aValue.Name.equalsAscii(PROPERTY_PERSISTENT_NAME) ) - { - aValue.Value >>= sPersistentName; - } - else if ( aValue.Name.equalsAscii(PROPERTY_EMBEDDEDOBJECT) ) - { - xCopyFrom.set(aValue.Value,UNO_QUERY); - } - else if ( aValue.Name.equalsAscii(PROPERTY_URL) ) - { - aValue.Value >>= sURL; - } - else if ( aValue.Name.equalsAscii(PROPERTY_ACTIVE_CONNECTION) ) - { - xConnection.set(aValue.Value,UNO_QUERY); - } - else if ( aValue.Name.equalsAscii("ClassID") ) - { - if (! ( aValue.Value >>= aClassID ) ) - { - // Extended for usage also with a string - ::rtl::OUString suValue; - aValue.Value >>= suValue; - aClassID = ::comphelper::MimeConfigurationHelper::GetSequenceClassIDRepresentation( suValue ); + ::comphelper::NamedValueCollection aArgs( _aArguments ); + sName = aArgs.getOrDefault( (::rtl::OUString)PROPERTY_NAME, sName ); + sPersistentName = aArgs.getOrDefault( (::rtl::OUString)PROPERTY_PERSISTENT_NAME, sPersistentName ); + xCopyFrom = aArgs.getOrDefault( (::rtl::OUString)PROPERTY_EMBEDDEDOBJECT, xCopyFrom ); + sURL = aArgs.getOrDefault( (::rtl::OUString)PROPERTY_URL, sURL ); + xConnection = aArgs.getOrDefault( (::rtl::OUString)PROPERTY_ACTIVE_CONNECTION, xConnection ); + bAsTemplate = aArgs.getOrDefault( (::rtl::OUString)PROPERTY_AS_TEMPLATE, bAsTemplate ); + sMediaType = aArgs.getOrDefault( (::rtl::OUString)INFO_MEDIATYPE, sMediaType ); - } - rtl::OUString suClassID = ::comphelper::MimeConfigurationHelper::GetStringClassIDRepresentation(aClassID); - volatile int dummy = 0; - (void)dummy; - (void)suClassID; - } - else if ( aValue.Name.equalsAscii(PROPERTY_AS_TEMPLATE) ) - { - aValue.Value >>= bAsTemplate; - } - else + if ( aArgs.has( "ClassID" ) ) + { + Any aClassIDValue = aArgs.get( "ClassID" ); + // class IDs might be passed as byte sequence ... + if ( !( aClassIDValue >>= aClassID ) ) { - // DBG_ASSERT("unknown property exception"); + // ... or as string + ::rtl::OUString sClassID; + aClassIDValue >>= sClassID; + aClassID = ::comphelper::MimeConfigurationHelper::GetSequenceClassIDRepresentation( sClassID ); } } @@ -282,6 +255,7 @@ Reference< XInterface > SAL_CALL ODocumentContainer::createInstanceWithArguments if ( xElements.is() ) sPersistentName = ::dbtools::createUniqueName(xElements,sPersistentName); + const bool bNeedClassID = ( aClassID.getLength() == 0 ) && ( 0 == sURL.getLength() ); if ( xCopyFrom.is() ) { Sequence<Any> aIni(2); @@ -295,10 +269,16 @@ Reference< XInterface > SAL_CALL ODocumentContainer::createInstanceWithArguments 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 ( ( aClassID.getLength() == 0 ) && ( 0 == sURL.getLength() ) ) - ODocumentDefinition::GetDocumentServiceFromMediaType( getContainerStorage(), sPersistentName, m_aContext, aClassID ); + // 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 && sMediaType.getLength() ) + ODocumentDefinition::GetDocumentServiceFromMediaType( sMediaType, m_aContext, aClassID ); + } } ODefinitionContainer_Impl::const_iterator aFind = rDefinitions.find( sName ); diff --git a/dbaccess/source/core/dataaccess/documentdefinition.cxx b/dbaccess/source/core/dataaccess/documentdefinition.cxx index 8a4cff9624ae..992fc156d386 100644 --- a/dbaccess/source/core/dataaccess/documentdefinition.cxx +++ b/dbaccess/source/core/dataaccess/documentdefinition.cxx @@ -422,7 +422,7 @@ namespace dbaccess //================================================================== typedef ::cppu::WeakImplHelper1 < css::lang::XEventListener > LifetimeCoupler_Base; - /** helper class which couples the lifetime of a component to the lifetim + /** 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 @@ -617,13 +617,12 @@ void SAL_CALL ODocumentDefinition::disposing() ::osl::MutexGuard aGuard(m_aMutex); closeObject(); ::comphelper::disposeComponent(m_xListener); - if ( m_bRemoveListener && m_xDesktop.is() ) + if ( m_bRemoveListener ) { Reference<util::XCloseable> xCloseable(m_pImpl->m_pDataSource->getModel_noCreate(),UNO_QUERY); if ( xCloseable.is() ) xCloseable->removeCloseListener(this); } - m_xDesktop = NULL; } // ----------------------------------------------------------------------------- IMPLEMENT_TYPEPROVIDER3(ODocumentDefinition,OContentHelper,OPropertyStateContainer,ODocumentDefinition_Base); @@ -690,17 +689,15 @@ namespace } // ----------------------------------------------------------------------------- -void ODocumentDefinition::impl_removeFrameFromDesktop_throw( const Reference< XFrame >& _rxFrame ) +void ODocumentDefinition::impl_removeFrameFromDesktop_throw( const ::comphelper::ComponentContext& _rContxt, const Reference< XFrame >& _rxFrame ) { - if ( !m_xDesktop.is() ) - m_xDesktop.set( m_aContext.createComponent( (::rtl::OUString)SERVICE_FRAME_DESKTOP ), UNO_QUERY_THROW ); - - Reference< XFrames > xFrames( m_xDesktop->getFrames(), UNO_QUERY_THROW ); + 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() +void ODocumentDefinition::impl_onActivateEmbeddedObject_nothrow() { try { @@ -712,26 +709,23 @@ void ODocumentDefinition::impl_onActivateEmbeddedObject() 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); + m_xListener = new OEmbedObjectHolder( m_xEmbeddedObject, this ); - Reference< XFrame > xFrame( xController->getFrame() ); - if ( xFrame.is() ) - { - // raise the window to top (especially necessary if this is not the first activation) - Reference< XTopWindow > xTopWindow( xFrame->getContainerWindow(), UNO_QUERY_THROW ); - xTopWindow->toFront(); + // 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( xFrame ); - } + // 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, Reference< XComponent >( xFrame, UNO_QUERY_THROW ) ); // init the edit view - if ( m_bOpenInDesign ) - impl_initObjectEditView( xController ); + if ( m_bForm && m_bOpenInDesign ) + impl_initFormEditView( xController ); } catch( const RuntimeException& ) { @@ -833,12 +827,8 @@ namespace } // ----------------------------------------------------------------------------- -void ODocumentDefinition::impl_initObjectEditView( const Reference< XController >& _rxController ) +void ODocumentDefinition::impl_initFormEditView( const Reference< XController >& _rxController ) { - if ( !m_bForm ) - // currently, only forms need to be initialized - return; - try { Reference< XViewSettingsSupplier > xSettingsSupplier( _rxController, UNO_QUERY_THROW ); @@ -872,10 +862,10 @@ void ODocumentDefinition::impl_initObjectEditView( const Reference< XController } // ----------------------------------------------------------------------------- -void ODocumentDefinition::onCommandOpenSomething( const Any& _rOpenArgument, const bool _bActivate, - const Reference< XCommandEnvironment >& _rxEnvironment, Any& _out_rComponent, ::osl::ClearableMutexGuard & _aGuard ) +Any ODocumentDefinition::onCommandOpenSomething( const Any& _rOpenArgument, const bool _bActivate, + const Reference< XCommandEnvironment >& _rxEnvironment ) { - OExecuteImpl aExecuteGuard(m_bInExecute); + OExecuteImpl aExecuteGuard( m_bInExecute ); Reference< XConnection > xConnection; sal_Int32 nOpenMode = OpenMode::DOCUMENT; @@ -885,7 +875,9 @@ void ODocumentDefinition::onCommandOpenSomething( const Any& _rOpenArgument, con // for the document, default to the interaction handler as used for loading the DB doc // This might be overwritten below, when examining _rOpenArgument. ::comphelper::NamedValueCollection aDBDocArgs( m_pImpl->m_pDataSource->getResource() ); - aDocumentArgs.put( "InteractionHandler", aDBDocArgs.getOrDefault( "InteractionHandler", Reference< XInteractionHandler >() ) ); + Reference< XInteractionHandler > xHandler( aDBDocArgs.getOrDefault( "InteractionHandler", Reference< XInteractionHandler >() ) ); + if ( xHandler.is() ) + aDocumentArgs.put( "InteractionHandler", xHandler ); ::boost::optional< sal_Int16 > aDocumentMacroMode; @@ -999,7 +991,7 @@ void ODocumentDefinition::onCommandOpenSomething( const Any& _rOpenArgument, con OSL_ENSURE( m_pImpl->m_aProps.sPersistentName.getLength(), "ODocumentDefinition::onCommandOpenSomething: no persistent name - cannot load!" ); if ( !m_pImpl->m_aProps.sPersistentName.getLength() ) - return; + 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. @@ -1009,7 +1001,7 @@ void ODocumentDefinition::onCommandOpenSomething( const Any& _rOpenArgument, con 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; + return Any(); Reference< XModel > xModel( getComponent(), UNO_QUERY ); Reference< report::XReportDefinition > xReportDefinition(xModel,UNO_QUERY); @@ -1035,158 +1027,169 @@ void ODocumentDefinition::onCommandOpenSomething( const Any& _rOpenArgument, con xReportEngine->setReportDefinition(xReportDefinition); xReportEngine->setActiveConnection(m_xLastKnownConnection); if ( bOpenHidden ) - _out_rComponent <<= xReportEngine->createDocumentModel( ); - else - _out_rComponent <<= xReportEngine->createDocumentAlive(NULL); - return; + return makeAny( xReportEngine->createDocumentModel() ); + return makeAny( xReportEngine->createDocumentAlive( NULL ) ); } if ( _bActivate && !bOpenHidden ) { m_xEmbeddedObject->changeState( EmbedStates::ACTIVE ); - impl_onActivateEmbeddedObject(); + ODocumentDefinition::impl_onActivateEmbeddedObject_nothrow(); } - // LLA: Alle fillReportData() calls prfen, sollte es welche geben, die danach noch viel machen - // LLA: sollten wir einen _aGuard Pointer bergeben, sonst erstmal als Referenz - fillReportData(_aGuard); - _out_rComponent <<= xModel; + 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; - ::osl::ClearableMutexGuard aGuard(m_aMutex); - if ( !m_bInExecute ) - { - 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 ) - { - 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 - // #i89509# / 2008-05-22 / frank.schoenheit@sun.com - if ( m_xEmbeddedObject.is() ) - { - sal_Int32 nCurrentState = m_xEmbeddedObject->getCurrentState(); - bool bIsActive = ( nCurrentState == EmbedStates::ACTIVE ); - - // exception: new-style reports always create a new document when "open" is executed - Reference< report::XReportDefinition > xReportDefinition( getComponent(), UNO_QUERY ); - bool bIsAliveNewStyleReport = ( xReportDefinition.is() && ( bOpen || bOpenForMail ) ); - - if ( bIsActive && !bIsAliveNewStyleReport ) - { - impl_onActivateEmbeddedObject(); - return makeAny( getComponent() ); - } - } - - // m_bOpenInDesign = bOpenInDesign; - // onCommandOpenSomething( aCommand.Argument, !bOpenForMail, Environment, aRet, aGuard ); - m_bOpenInDesign = bOpenInDesign || bOpenForMail; - onCommandOpenSomething( aCommand.Argument, bActivateObject, Environment, aRet, aGuard ); - } - else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "copyTo" ) ) ) + 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. + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ::osl::ClearableMutexGuard aGuard(m_aMutex); + if ( m_bInExecute ) + return aRet; + + bool bActivateObject = true; + if ( bOpenForMail ) { - 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); - /*loadEmbeddedObject( true ); - Reference<XEmbedPersist> xPersist(m_xEmbeddedObject,UNO_QUERY); - if ( xPersist.is() ) - { - xPersist->storeToEntry(xStorage,sPersistentName,Sequence<PropertyValue>(),Sequence<PropertyValue>()); - xPersist->storeOwn(); - m_xEmbeddedObject->changeState(EmbedStates::LOADED); - } - else - throw CommandAbortedException();*/ - } - else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "preview" ) ) ) - { - onCommandPreview(aRet); + OSL_ENSURE( false, "ODocumentDefinition::execute: 'openForMail' should not be used anymore - use the 'Hidden' parameter instead!" ); + bActivateObject = false; } - else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "insert" ) ) ) + + // if the object is already opened, do nothing + // #i89509# / 2008-05-22 / frank.schoenheit@sun.com + if ( m_xEmbeddedObject.is() ) { - Sequence<Any> aIni; - aCommand.Argument >>= aIni; - if ( aIni.getLength() > 0 && aIni.getLength() < 2 ) + sal_Int32 nCurrentState = m_xEmbeddedObject->getCurrentState(); + bool bIsActive = ( nCurrentState == EmbedStates::ACTIVE ); + + // exception: new-style reports always create a new document when "open" is executed + Reference< report::XReportDefinition > xReportDefinition( getComponent(), UNO_QUERY ); + bool bIsAliveNewStyleReport = ( xReportDefinition.is() && ( bOpen || bOpenForMail ) ); + + if ( bIsActive && !bIsAliveNewStyleReport ) { - OSL_ENSURE( sal_False, "Wrong argument type!" ); - ucbhelper::cancelCommandExecution( - makeAny( IllegalArgumentException( - rtl::OUString(), - static_cast< cppu::OWeakObject * >( this ), - -1 ) ), - Environment ); - // Unreachable + ODocumentDefinition::impl_onActivateEmbeddedObject_nothrow(); + return makeAny( getComponent() ); } - ::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(); + m_bOpenInDesign = bOpenInDesign || bOpenForMail; + return onCommandOpenSomething( aCommand.Argument, bActivateObject, Environment ); + } - } - else if ( ( aCommand.Name.compareToAscii( "storeOwn" ) == 0 ) // compatibility - || ( aCommand.Name.compareToAscii( "store" ) == 0 ) - ) + ::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 ) { - impl_store_throw(); + 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.compareToAscii( "shutdown" ) == 0 ) // compatibility - || ( aCommand.Name.compareToAscii( "close" ) == 0 ) - ) + 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); + /*loadEmbeddedObject( true ); + Reference<XEmbedPersist> xPersist(m_xEmbeddedObject,UNO_QUERY); + if ( xPersist.is() ) { - aRet <<= impl_close_throw(); + xPersist->storeToEntry(xStorage,sPersistentName,Sequence<PropertyValue>(),Sequence<PropertyValue>()); + xPersist->storeOwn(); + m_xEmbeddedObject->changeState(EmbedStates::LOADED); } else + throw CommandAbortedException();*/ + } + 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() ) { - aRet = OContentHelper::execute(aCommand,CommandId,Environment); + 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 + { + aRet = OContentHelper::execute(aCommand,CommandId,Environment); + } + return aRet; } // ----------------------------------------------------------------------------- @@ -1607,9 +1610,8 @@ Sequence< PropertyValue > ODocumentDefinition::fillLoadArgs( const Reference< XC xParentFrame = lcl_getDatabaseDocumentFrame( *m_pImpl->m_pDataSource ); if ( !xParentFrame.is() ) { // i87957 we need a parent frame - if ( !m_xDesktop.is() ) - m_xDesktop.set( m_aContext.createComponent( (::rtl::OUString)SERVICE_FRAME_DESKTOP ), UNO_QUERY_THROW ); - xParentFrame.set(m_xDesktop,uno::UNO_QUERY); + 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); @@ -1918,10 +1920,8 @@ Reference< XComponent > ODocumentDefinition::impl_openUI_nolck_throw( bool _bFor { // no XDatabaseDocumentUI -> just execute the respective command m_bOpenInDesign = _bForEditing; - Any aComponent; - onCommandOpenSomething( Any(), true, NULL, aComponent, aGuard ); - Reference< XComponent > xComponent; - OSL_VERIFY( aComponent >>= xComponent ); + Reference< XComponent > xComponent( onCommandOpenSomething( Any(), true, NULL ), UNO_QUERY ); + OSL_ENSURE( xComponent.is(), "ODocumentDefinition::impl_openUI_nolck_throw: opening the thingie failed." ); return xComponent; } @@ -2122,26 +2122,29 @@ bool ODocumentDefinition::prepareClose() return true; } // ----------------------------------------------------------------------------- -void ODocumentDefinition::fillReportData(::osl::ClearableMutexGuard & _aGuard) +void ODocumentDefinition::fillReportData( const ::comphelper::ComponentContext& _rContext, + const Reference< util::XCloseable >& _rxComponent, + const Reference< XConnection >& _rxActiveConnection ) { - if ( !m_bForm && m_pImpl->m_aProps.bAsTemplate && !m_bOpenInDesign ) // open a report in alive mode, so we need to fill it - { - Sequence<Any> aArgs(2); - PropertyValue aValue; - aValue.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TextDocument")); - aValue.Value <<= getComponent(); - aArgs[0] <<= aValue; - aValue.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ActiveConnection")); - aValue.Value <<= m_xLastKnownConnection; - aArgs[1] <<= aValue; - - Reference< XJobExecutor > xExecuteable( m_aContext.createComponentWithArguments( "com.sun.star.wizards.report.CallReportWizard", aArgs ), UNO_QUERY ); - if ( xExecuteable.is() ) - { - _aGuard.clear(); - xExecuteable->trigger(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("fill"))); + 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() diff --git a/dbaccess/source/core/dataaccess/documentdefinition.hxx b/dbaccess/source/core/dataaccess/documentdefinition.hxx index 2d8d5f6df343..c48d20ad58a3 100644 --- a/dbaccess/source/core/dataaccess/documentdefinition.hxx +++ b/dbaccess/source/core/dataaccess/documentdefinition.hxx @@ -92,7 +92,6 @@ class ODocumentDefinition { ::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::frame::XFramesSupplier > m_xDesktop; ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > m_xLastKnownConnection; OInterceptor* m_pInterceptor; @@ -163,9 +162,17 @@ public: sal_Bool saveAs(); void closeObject(); sal_Bool isModified(); - void fillReportData(::osl::ClearableMutexGuard & _aGuard); 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 @@ -192,12 +199,10 @@ public: private: /** does necessary initializations after our embedded object has been switched to ACTIVE - @param _bOpenedInDesignMode - determines whether the embedded object has been opened for designing it or for data display */ - void impl_onActivateEmbeddedObject(); + void impl_onActivateEmbeddedObject_nothrow(); - /** initializes a newly created view/controller which is displaying our embedded object + /** 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) @@ -205,12 +210,15 @@ private: @param _rxController the controller which belongs to the XModel of our (active) embedded object */ - void impl_initObjectEditView( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController >& _rxController ); + 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 */ - void impl_removeFrameFromDesktop_throw( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& _rxFrame ); + 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 */ @@ -310,10 +318,12 @@ private: 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 ); - void onCommandOpenSomething( const ::com::sun::star::uno::Any& _rArgument, const bool _bActivate, - const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >& _rxEnvironment, - ::com::sun::star::uno::Any& _out_rComponent, - ::osl::ClearableMutexGuard & _aClearableGuard); + ::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 + ); }; //........................................................................ diff --git a/dbaccess/source/core/dataaccess/intercept.cxx b/dbaccess/source/core/dataaccess/intercept.cxx index 733f155dae5d..9211302f0d9b 100644 --- a/dbaccess/source/core/dataaccess/intercept.cxx +++ b/dbaccess/source/core/dataaccess/intercept.cxx @@ -31,28 +31,17 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_dbaccess.hxx" -#ifndef _COM_SUN_STAR_EMBED_EMBEDSTATES_HPP_ +#include "intercept.hxx" +#include "dbastrings.hrc" + #include <com/sun/star/embed/EmbedStates.hpp> -#endif -#ifndef _COM_SUN_STAR_DOCUMENT_XEVENTBROADCASTER_HPP_ #include <com/sun/star/document/XEventBroadcaster.hpp> -#endif -#ifndef _COM_SUN_STAR_UTIL_XMODIFIABLE_HPP_ #include <com/sun/star/util/XModifiable.hpp> -#endif -#ifndef _CPPUHELPER_WEAK_HXX_ #include <cppuhelper/weak.hxx> -#endif -#ifndef _COMPHELPER_TYPES_HXX_ + #include <comphelper/types.hxx> -#endif -#ifndef DBA_INTERCEPT_HXX -#include "intercept.hxx" -#endif -#include "dbastrings.hrc" -#ifndef _TOOLS_DEBUG_HXX #include <tools/debug.hxx> -#endif +#include <tools/diagnose_ex.h> namespace dbaccess @@ -140,66 +129,78 @@ struct DispatchHelper //XDispatch void SAL_CALL OInterceptor::dispatch( const URL& _URL,const Sequence<PropertyValue >& Arguments ) throw (RuntimeException) { - osl::ClearableMutexGuard aClearableGuard(m_aMutex); - if( m_pContentHolder ) + ::osl::MutexGuard aGuard( m_aMutex ); + if ( !m_pContentHolder ) + return; + + if ( _URL.Complete == m_aInterceptedURL[ DISPATCH_SAVE ] ) { - if( _URL.Complete == m_aInterceptedURL[DISPATCH_SAVE] ) - { - m_pContentHolder->save(sal_False); - } - else if( _URL.Complete == m_aInterceptedURL[DISPATCH_RELOAD] ) + 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->fillReportData(aClearableGuard); - // IMPORTANT: m_aMutex is cleared! + m_pContentHolder->saveAs(); } - else if( _URL.Complete == m_aInterceptedURL[DISPATCH_SAVEAS] ) + else if ( m_xSlaveDispatchProvider.is() ) { - if ( m_pContentHolder->isNewReport() ) - { - m_pContentHolder->saveAs(); - } - else if ( m_xSlaveDispatchProvider.is() ) - { - Sequence< PropertyValue > aNewArgs = Arguments; - sal_Int32 nInd = 0; + 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() ) + while( nInd < aNewArgs.getLength() ) + { + if ( aNewArgs[nInd].Name.equalsAscii( "SaveTo" ) ) { - aNewArgs.realloc( nInd + 1 ); - aNewArgs[nInd].Name = ::rtl::OUString::createFromAscii( "SaveTo" ); aNewArgs[nInd].Value <<= sal_True; + break; } + nInd++; + } - Reference< XDispatch > xDispatch = m_xSlaveDispatchProvider->queryDispatch( - _URL, ::rtl::OUString::createFromAscii( "_self" ), 0 ); - if ( xDispatch.is() ) - xDispatch->dispatch( _URL, aNewArgs ); + 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 ); } - else 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; + } + + 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*, _nId) + +IMPL_LINK( OInterceptor, OnDispatch, void*, _pDispatcher ) { - ::std::auto_ptr<DispatchHelper> pHelper(reinterpret_cast<DispatchHelper*>(_nId)); + ::std::auto_ptr<DispatchHelper> pHelper( reinterpret_cast< DispatchHelper* >( _pDispatcher ) ); try { if ( m_pContentHolder && m_pContentHolder->prepareClose() && m_xSlaveDispatchProvider.is() ) @@ -217,10 +218,11 @@ IMPL_LINK( OInterceptor, OnDispatch, void*, _nId) } } } - catch(const Exception&) + catch ( const Exception& ) { - OSL_ENSURE(sal_False, "caught an exception while starting the table wizard!"); + DBG_UNHANDLED_EXCEPTION(); } + return 0L; } diff --git a/dbaccess/source/core/inc/ContentHelper.hxx b/dbaccess/source/core/inc/ContentHelper.hxx index 227110bd324d..d9d000435ec4 100644 --- a/dbaccess/source/core/inc/ContentHelper.hxx +++ b/dbaccess/source/core/inc/ContentHelper.hxx @@ -236,6 +236,8 @@ namespace dbaccess getPropertyValues( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& rProperties ); + const ::comphelper::ComponentContext& getContext() const { return m_aContext; } + inline TContentPtr getImpl() const { return m_pImpl; } protected: |