| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_embeddedobj.hxx" |
| #include <com/sun/star/embed/ElementModes.hpp> |
| #include <com/sun/star/embed/EntryInitModes.hpp> |
| #include <com/sun/star/embed/XEmbedObjectFactory.hpp> |
| #include <com/sun/star/embed/XLinkFactory.hpp> |
| #include <com/sun/star/document/XTypeDetection.hpp> |
| #include <com/sun/star/beans/PropertyValue.hpp> |
| #include <com/sun/star/beans/XPropertySet.hpp> |
| #include <com/sun/star/container/XNameAccess.hpp> |
| #include <com/sun/star/lang/XComponent.hpp> |
| |
| #include <rtl/logfile.hxx> |
| |
| |
| #include <xcreator.hxx> |
| #include <dummyobject.hxx> |
| |
| |
| using namespace ::com::sun::star; |
| |
| |
| //------------------------------------------------------------------------- |
| uno::Sequence< ::rtl::OUString > SAL_CALL UNOEmbeddedObjectCreator::impl_staticGetSupportedServiceNames() |
| { |
| uno::Sequence< ::rtl::OUString > aRet(2); |
| aRet[0] = ::rtl::OUString::createFromAscii("com.sun.star.embed.EmbeddedObjectCreator"); |
| aRet[1] = ::rtl::OUString::createFromAscii("com.sun.star.comp.embed.EmbeddedObjectCreator"); |
| return aRet; |
| } |
| |
| //------------------------------------------------------------------------- |
| ::rtl::OUString SAL_CALL UNOEmbeddedObjectCreator::impl_staticGetImplementationName() |
| { |
| return ::rtl::OUString::createFromAscii("com.sun.star.comp.embed.EmbeddedObjectCreator"); |
| } |
| |
| //------------------------------------------------------------------------- |
| uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::impl_staticCreateSelfInstance( |
| const uno::Reference< lang::XMultiServiceFactory >& xServiceManager ) |
| { |
| return uno::Reference< uno::XInterface >( *new UNOEmbeddedObjectCreator( xServiceManager ) ); |
| } |
| |
| //------------------------------------------------------------------------- |
| uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInstanceInitNew( |
| const uno::Sequence< sal_Int8 >& aClassID, |
| const ::rtl::OUString& aClassName, |
| const uno::Reference< embed::XStorage >& xStorage, |
| const ::rtl::OUString& sEntName, |
| const uno::Sequence< beans::PropertyValue >& lObjArgs ) |
| throw ( lang::IllegalArgumentException, |
| io::IOException, |
| uno::Exception, |
| uno::RuntimeException) |
| { |
| RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceInitNew" ); |
| |
| uno::Reference< uno::XInterface > xResult; |
| |
| if ( !xStorage.is() ) |
| throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ), |
| uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ), |
| 3 ); |
| |
| if ( !sEntName.getLength() ) |
| throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ), |
| uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ), |
| 4 ); |
| |
| ::rtl::OUString aEmbedFactory = m_aConfigHelper.GetFactoryNameByClassID( aClassID ); |
| if ( !aEmbedFactory.getLength() ) |
| { |
| // use system fallback |
| // TODO: in future users factories can be tested |
| aEmbedFactory = ::rtl::OUString::createFromAscii( "com.sun.star.embed.OLEEmbeddedObjectFactory" ); |
| } |
| |
| uno::Reference < uno::XInterface > xFact( m_xFactory->createInstance( aEmbedFactory ) ); |
| uno::Reference< embed::XEmbedObjectCreator > xEmbCreator( xFact, uno::UNO_QUERY ); |
| if ( xEmbCreator.is() ) |
| return xEmbCreator->createInstanceInitNew( aClassID, aClassName, xStorage, sEntName, lObjArgs ); |
| |
| uno::Reference < embed::XEmbedObjectFactory > xEmbFact( xFact, uno::UNO_QUERY ); |
| if ( !xEmbFact.is() ) |
| throw uno::RuntimeException(); |
| return xEmbFact->createInstanceUserInit( aClassID, aClassName, xStorage, sEntName, embed::EntryInitModes::TRUNCATE_INIT, uno::Sequence < beans::PropertyValue >(), lObjArgs); |
| } |
| |
| //------------------------------------------------------------------------- |
| uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInstanceInitFromEntry( |
| const uno::Reference< embed::XStorage >& xStorage, |
| const ::rtl::OUString& sEntName, |
| const uno::Sequence< beans::PropertyValue >& aMedDescr, |
| const uno::Sequence< beans::PropertyValue >& lObjArgs ) |
| throw ( lang::IllegalArgumentException, |
| container::NoSuchElementException, |
| io::IOException, |
| uno::Exception, |
| uno::RuntimeException) |
| { |
| RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceInitFromEntry" ); |
| |
| if ( !xStorage.is() ) |
| throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ), |
| uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ), |
| 1 ); |
| |
| if ( !sEntName.getLength() ) |
| throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ), |
| uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ), |
| 2 ); |
| |
| uno::Reference< container::XNameAccess > xNameAccess( xStorage, uno::UNO_QUERY ); |
| if ( !xNameAccess.is() ) |
| throw uno::RuntimeException(); //TODO |
| |
| // detect entry existence |
| if ( !xNameAccess->hasByName( sEntName ) ) |
| throw container::NoSuchElementException(); |
| |
| ::rtl::OUString aMediaType; |
| ::rtl::OUString aEmbedFactory; |
| if ( xStorage->isStorageElement( sEntName ) ) |
| { |
| // the object must be based on storage |
| uno::Reference< embed::XStorage > xSubStorage = |
| xStorage->openStorageElement( sEntName, embed::ElementModes::READ ); |
| |
| uno::Reference< beans::XPropertySet > xPropSet( xSubStorage, uno::UNO_QUERY ); |
| if ( !xPropSet.is() ) |
| throw uno::RuntimeException(); |
| |
| try { |
| uno::Any aAny = xPropSet->getPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ) ); |
| aAny >>= aMediaType; |
| } |
| catch ( uno::Exception& ) |
| { |
| } |
| |
| try { |
| uno::Reference< lang::XComponent > xComp( xSubStorage, uno::UNO_QUERY ); |
| if ( xComp.is() ) |
| xComp->dispose(); |
| } |
| catch ( uno::Exception& ) |
| { |
| } |
| } |
| else |
| { |
| // the object must be based on stream |
| // it means for now that this is an OLE object |
| |
| // the object will be created as embedded object |
| // after it is loaded it can detect that it is a link |
| |
| uno::Reference< io::XStream > xSubStream = |
| xStorage->openStreamElement( sEntName, embed::ElementModes::READ ); |
| |
| uno::Reference< beans::XPropertySet > xPropSet( xSubStream, uno::UNO_QUERY ); |
| if ( !xPropSet.is() ) |
| throw uno::RuntimeException(); |
| |
| try { |
| uno::Any aAny = xPropSet->getPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ) ); |
| aAny >>= aMediaType; |
| if ( aMediaType.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/vnd.sun.star.oleobject" ) ) ) ) |
| aEmbedFactory = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.OLEEmbeddedObjectFactory" ) ); |
| } |
| catch ( uno::Exception& ) |
| { |
| } |
| |
| try { |
| uno::Reference< lang::XComponent > xComp( xSubStream, uno::UNO_QUERY ); |
| if ( xComp.is() ) |
| xComp->dispose(); |
| } |
| catch ( uno::Exception& ) |
| { |
| } |
| } |
| |
| OSL_ENSURE( aMediaType.getLength(), "No media type is specified for the object!" ); |
| if ( aMediaType.getLength() && !aEmbedFactory.getLength() ) |
| aEmbedFactory = m_aConfigHelper.GetFactoryNameByMediaType( aMediaType ); |
| |
| if ( aEmbedFactory.getLength() ) |
| { |
| uno::Reference< uno::XInterface > xFact = m_xFactory->createInstance( aEmbedFactory ); |
| |
| uno::Reference< embed::XEmbedObjectCreator > xEmbCreator( xFact, uno::UNO_QUERY ); |
| if ( xEmbCreator.is() ) |
| return xEmbCreator->createInstanceInitFromEntry( xStorage, sEntName, aMedDescr, lObjArgs ); |
| |
| uno::Reference < embed::XEmbedObjectFactory > xEmbFact( xFact, uno::UNO_QUERY ); |
| if ( xEmbFact.is() ) |
| return xEmbFact->createInstanceUserInit( uno::Sequence< sal_Int8 >(), ::rtl::OUString(), xStorage, sEntName, embed::EntryInitModes::DEFAULT_INIT, aMedDescr, lObjArgs); |
| } |
| |
| // the default object should be created, it will allow to store the contents on the next saving |
| uno::Reference< uno::XInterface > xResult( static_cast< cppu::OWeakObject* >( new ODummyEmbeddedObject() ) ); |
| uno::Reference< embed::XEmbedPersist > xPersist( xResult, uno::UNO_QUERY_THROW ); |
| xPersist->setPersistentEntry( xStorage, sEntName, embed::EntryInitModes::DEFAULT_INIT, aMedDescr, lObjArgs ); |
| return xResult; |
| } |
| |
| //------------------------------------------------------------------------- |
| uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInstanceInitFromMediaDescriptor( |
| const uno::Reference< embed::XStorage >& xStorage, |
| const ::rtl::OUString& sEntName, |
| const uno::Sequence< beans::PropertyValue >& aMediaDescr, |
| const uno::Sequence< beans::PropertyValue >& lObjArgs ) |
| throw ( lang::IllegalArgumentException, |
| io::IOException, |
| uno::Exception, |
| uno::RuntimeException) |
| { |
| RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceInitFromMediaDescriptor" ); |
| |
| // TODO: use lObjArgs |
| |
| if ( !xStorage.is() ) |
| throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ), |
| uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ), |
| 1 ); |
| |
| if ( !sEntName.getLength() ) |
| throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ), |
| uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ), |
| 2 ); |
| |
| uno::Reference< uno::XInterface > xResult; |
| uno::Sequence< beans::PropertyValue > aTempMedDescr( aMediaDescr ); |
| |
| // check if there is FilterName |
| ::rtl::OUString aFilterName = m_aConfigHelper.UpdateMediaDescriptorWithFilterName( aTempMedDescr, sal_False ); |
| |
| if ( aFilterName.getLength() ) |
| { |
| // the object can be loaded by one of the office application |
| uno::Reference< embed::XEmbedObjectCreator > xOOoEmbCreator( |
| m_xFactory->createInstance( |
| ::rtl::OUString::createFromAscii( "com.sun.star.embed.OOoEmbeddedObjectFactory" ) ), |
| uno::UNO_QUERY ); |
| if ( !xOOoEmbCreator.is() ) |
| throw uno::RuntimeException(); // TODO: |
| |
| xResult = xOOoEmbCreator->createInstanceInitFromMediaDescriptor( xStorage, |
| sEntName, |
| aTempMedDescr, |
| lObjArgs ); |
| } |
| else |
| { |
| // must be an OLE object |
| |
| // TODO: in future, when more object types are possible this place seems |
| // to be a weak one, probably configuration must provide a type detection service |
| // for every factory, so any file could go through services until it is recognized |
| // or there is no more services |
| // Or for example the typename can be used to detect object type if typedetection |
| // was also extended. |
| |
| uno::Reference< embed::XEmbedObjectCreator > xOleEmbCreator( |
| m_xFactory->createInstance( |
| ::rtl::OUString::createFromAscii( "com.sun.star.embed.OLEEmbeddedObjectFactory" ) ), |
| uno::UNO_QUERY ); |
| if ( !xOleEmbCreator.is() ) |
| throw uno::RuntimeException(); // TODO: |
| |
| xResult = xOleEmbCreator->createInstanceInitFromMediaDescriptor( xStorage, sEntName, aTempMedDescr, lObjArgs ); |
| } |
| |
| return xResult; |
| } |
| |
| //------------------------------------------------------------------------- |
| uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInstanceUserInit( |
| const uno::Sequence< sal_Int8 >& aClassID, |
| const ::rtl::OUString& sClassName, |
| const uno::Reference< embed::XStorage >& xStorage, |
| const ::rtl::OUString& sEntName, |
| sal_Int32 nEntryConnectionMode, |
| const uno::Sequence< beans::PropertyValue >& aArgs, |
| const uno::Sequence< beans::PropertyValue >& aObjectArgs ) |
| throw ( lang::IllegalArgumentException, |
| io::IOException, |
| uno::Exception, |
| uno::RuntimeException) |
| { |
| RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceUserInit" ); |
| |
| uno::Reference< uno::XInterface > xResult; |
| |
| if ( !xStorage.is() ) |
| throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ), |
| uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ), |
| 3 ); |
| |
| if ( !sEntName.getLength() ) |
| throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ), |
| uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ), |
| 4 ); |
| |
| ::rtl::OUString aEmbedFactory = m_aConfigHelper.GetFactoryNameByClassID( aClassID ); |
| uno::Reference< embed::XEmbedObjectFactory > xEmbFactory( |
| m_xFactory->createInstance( aEmbedFactory ), |
| uno::UNO_QUERY ); |
| if ( !xEmbFactory.is() ) |
| throw uno::RuntimeException(); // TODO: |
| |
| return xEmbFactory->createInstanceUserInit( aClassID, |
| sClassName, |
| xStorage, |
| sEntName, |
| nEntryConnectionMode, |
| aArgs, |
| aObjectArgs ); |
| } |
| |
| //------------------------------------------------------------------------- |
| uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInstanceLink( |
| const uno::Reference< embed::XStorage >& xStorage, |
| const ::rtl::OUString& sEntName, |
| const uno::Sequence< beans::PropertyValue >& aMediaDescr, |
| const uno::Sequence< beans::PropertyValue >& lObjArgs ) |
| throw ( lang::IllegalArgumentException, |
| io::IOException, |
| uno::Exception, |
| uno::RuntimeException ) |
| { |
| RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceLink" ); |
| |
| uno::Reference< uno::XInterface > xResult; |
| |
| uno::Sequence< beans::PropertyValue > aTempMedDescr( aMediaDescr ); |
| |
| // check if there is URL, URL must exist |
| ::rtl::OUString aURL; |
| for ( sal_Int32 nInd = 0; nInd < aTempMedDescr.getLength(); nInd++ ) |
| if ( aTempMedDescr[nInd].Name.equalsAscii( "URL" ) ) |
| aTempMedDescr[nInd].Value >>= aURL; |
| |
| if ( !aURL.getLength() ) |
| throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No URL for the link is provided!\n" ), |
| uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ), |
| 3 ); |
| |
| ::rtl::OUString aFilterName = m_aConfigHelper.UpdateMediaDescriptorWithFilterName( aTempMedDescr, sal_False ); |
| |
| if ( aFilterName.getLength() ) |
| { |
| // the object can be loaded by one of the office application |
| uno::Reference< embed::XLinkCreator > xOOoLinkCreator( |
| m_xFactory->createInstance( |
| ::rtl::OUString::createFromAscii( "com.sun.star.embed.OOoEmbeddedObjectFactory" ) ), |
| uno::UNO_QUERY ); |
| if ( !xOOoLinkCreator.is() ) |
| throw uno::RuntimeException(); // TODO: |
| |
| xResult = xOOoLinkCreator->createInstanceLink( xStorage, |
| sEntName, |
| aTempMedDescr, |
| lObjArgs ); |
| } |
| else |
| { |
| // must be an OLE link |
| |
| // TODO: in future, when more object types are possible this place seems |
| // to be a weak one, probably configuration must provide a type detection service |
| // for every factory, so any file could go through services until it is recognized |
| // or there is no more services |
| // Or for example the typename can be used to detect object type if typedetection |
| // was also extended. |
| |
| if ( !xStorage.is() ) |
| throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ), |
| uno::Reference< uno::XInterface >( |
| static_cast< ::cppu::OWeakObject* >(this) ), |
| 3 ); |
| |
| if ( !sEntName.getLength() ) |
| throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ), |
| uno::Reference< uno::XInterface >( |
| static_cast< ::cppu::OWeakObject* >(this) ), |
| 4 ); |
| |
| uno::Reference< embed::XLinkCreator > xLinkCreator( |
| m_xFactory->createInstance( |
| ::rtl::OUString::createFromAscii( "com.sun.star.embed.OLEEmbeddedObjectFactory" ) ), |
| uno::UNO_QUERY ); |
| if ( !xLinkCreator.is() ) |
| throw uno::RuntimeException(); // TODO: |
| |
| xResult = xLinkCreator->createInstanceLink( xStorage, sEntName, aTempMedDescr, lObjArgs ); |
| } |
| |
| return xResult; |
| } |
| |
| //------------------------------------------------------------------------- |
| uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInstanceLinkUserInit( |
| const uno::Sequence< sal_Int8 >& aClassID, |
| const ::rtl::OUString& aClassName, |
| const uno::Reference< embed::XStorage >& xStorage, |
| const ::rtl::OUString& sEntName, |
| const uno::Sequence< beans::PropertyValue >& lArguments, |
| const uno::Sequence< beans::PropertyValue >& lObjArgs ) |
| throw ( lang::IllegalArgumentException, |
| io::IOException, |
| uno::Exception, |
| uno::RuntimeException ) |
| { |
| RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceLinkUserInit" ); |
| |
| uno::Reference< uno::XInterface > xResult; |
| |
| ::rtl::OUString aEmbedFactory = m_aConfigHelper.GetFactoryNameByClassID( aClassID ); |
| uno::Reference< embed::XLinkFactory > xLinkFactory( |
| m_xFactory->createInstance( aEmbedFactory ), |
| uno::UNO_QUERY ); |
| if ( !xLinkFactory.is() ) |
| throw uno::RuntimeException(); // TODO: |
| |
| return xLinkFactory->createInstanceLinkUserInit( aClassID, |
| aClassName, |
| xStorage, |
| sEntName, |
| lArguments, |
| lObjArgs ); |
| |
| } |
| |
| //------------------------------------------------------------------------- |
| ::rtl::OUString SAL_CALL UNOEmbeddedObjectCreator::getImplementationName() |
| throw ( uno::RuntimeException ) |
| { |
| return impl_staticGetImplementationName(); |
| } |
| |
| //------------------------------------------------------------------------- |
| sal_Bool SAL_CALL UNOEmbeddedObjectCreator::supportsService( const ::rtl::OUString& ServiceName ) |
| throw ( uno::RuntimeException ) |
| { |
| uno::Sequence< ::rtl::OUString > aSeq = impl_staticGetSupportedServiceNames(); |
| |
| for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ ) |
| if ( ServiceName.compareTo( aSeq[nInd] ) == 0 ) |
| return sal_True; |
| |
| return sal_False; |
| } |
| |
| //------------------------------------------------------------------------- |
| uno::Sequence< ::rtl::OUString > SAL_CALL UNOEmbeddedObjectCreator::getSupportedServiceNames() |
| throw ( uno::RuntimeException ) |
| { |
| return impl_staticGetSupportedServiceNames(); |
| } |
| |