LCOV - code coverage report
Current view: top level - embeddedobj/source/general - xcreator.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 84 136 61.8 %
Date: 2015-06-13 12:38:46 Functions: 8 11 72.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <com/sun/star/embed/ElementModes.hpp>
      21             : #include <com/sun/star/embed/EntryInitModes.hpp>
      22             : #include <com/sun/star/embed/XEmbedObjectFactory.hpp>
      23             : #include <com/sun/star/embed/OOoEmbeddedObjectFactory.hpp>
      24             : #include <com/sun/star/embed/OLEEmbeddedObjectFactory.hpp>
      25             : #include <com/sun/star/embed/XLinkFactory.hpp>
      26             : #include <com/sun/star/document/XTypeDetection.hpp>
      27             : #include <com/sun/star/beans/PropertyValue.hpp>
      28             : #include <com/sun/star/beans/XPropertySet.hpp>
      29             : #include <com/sun/star/container/XNameAccess.hpp>
      30             : #include <com/sun/star/lang/XComponent.hpp>
      31             : 
      32             : #include <comphelper/processfactory.hxx>
      33             : #include <cppuhelper/supportsservice.hxx>
      34             : #include <comphelper/documentconstants.hxx>
      35             : 
      36             : #include <xcreator.hxx>
      37             : #include <dummyobject.hxx>
      38             : 
      39             : 
      40             : using namespace ::com::sun::star;
      41             : 
      42             : 
      43             : 
      44          33 : uno::Sequence< OUString > SAL_CALL UNOEmbeddedObjectCreator::impl_staticGetSupportedServiceNames()
      45             : {
      46          33 :     uno::Sequence< OUString > aRet(2);
      47          33 :     aRet[0] = "com.sun.star.embed.EmbeddedObjectCreator";
      48          33 :     aRet[1] = "com.sun.star.comp.embed.EmbeddedObjectCreator";
      49          33 :     return aRet;
      50             : }
      51             : 
      52             : 
      53          65 : OUString SAL_CALL UNOEmbeddedObjectCreator::impl_staticGetImplementationName()
      54             : {
      55          65 :     return OUString("com.sun.star.comp.embed.EmbeddedObjectCreator");
      56             : }
      57             : 
      58             : 
      59          32 : uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::impl_staticCreateSelfInstance(
      60             :             const uno::Reference< lang::XMultiServiceFactory >& xServiceManager )
      61             : {
      62          32 :     return uno::Reference< uno::XInterface >( *new UNOEmbeddedObjectCreator( comphelper::getComponentContext(xServiceManager) ) );
      63             : }
      64             : 
      65             : 
      66         507 : uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInstanceInitNew(
      67             :                                             const uno::Sequence< sal_Int8 >& aClassID,
      68             :                                             const OUString& aClassName,
      69             :                                             const uno::Reference< embed::XStorage >& xStorage,
      70             :                                             const OUString& sEntName,
      71             :                                             const uno::Sequence< beans::PropertyValue >& lObjArgs )
      72             :     throw ( lang::IllegalArgumentException,
      73             :             io::IOException,
      74             :             uno::Exception,
      75             :             uno::RuntimeException, std::exception)
      76             : {
      77         507 :     uno::Reference< uno::XInterface > xResult;
      78             : 
      79         507 :     if ( !xStorage.is() )
      80             :         throw lang::IllegalArgumentException( "No parent storage is provided!",
      81             :                                             static_cast< ::cppu::OWeakObject* >(this),
      82           0 :                                             3 );
      83             : 
      84         507 :     if ( sEntName.isEmpty() )
      85             :         throw lang::IllegalArgumentException( "Empty element name is provided!",
      86             :                                             static_cast< ::cppu::OWeakObject* >(this),
      87           0 :                                             4 );
      88             : 
      89        1014 :     OUString aEmbedFactory = m_aConfigHelper.GetFactoryNameByClassID( aClassID );
      90         507 :     if ( aEmbedFactory.isEmpty() )
      91             :     {
      92             :         // use system fallback
      93             :         // TODO: in future users factories can be tested
      94           0 :         aEmbedFactory = "com.sun.star.embed.OLEEmbeddedObjectFactory";
      95             :     }
      96             : 
      97        1014 :     uno::Reference < uno::XInterface > xFact( m_xContext->getServiceManager()->createInstanceWithContext(aEmbedFactory, m_xContext) );
      98        1014 :     uno::Reference< embed::XEmbedObjectCreator > xEmbCreator( xFact, uno::UNO_QUERY );
      99         507 :     if ( xEmbCreator.is() )
     100         499 :         return xEmbCreator->createInstanceInitNew( aClassID, aClassName, xStorage, sEntName, lObjArgs );
     101             : 
     102          16 :     uno::Reference < embed::XEmbedObjectFactory > xEmbFact( xFact, uno::UNO_QUERY );
     103           8 :     if ( !xEmbFact.is() )
     104           0 :         throw uno::RuntimeException();
     105         515 :     return xEmbFact->createInstanceUserInit( aClassID, aClassName, xStorage, sEntName, embed::EntryInitModes::TRUNCATE_INIT, uno::Sequence < beans::PropertyValue >(), lObjArgs);
     106             : }
     107             : 
     108             : 
     109         155 : uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInstanceInitFromEntry(
     110             :                                                                     const uno::Reference< embed::XStorage >& xStorage,
     111             :                                                                     const OUString& sEntName,
     112             :                                                                     const uno::Sequence< beans::PropertyValue >& aMedDescr,
     113             :                                                                     const uno::Sequence< beans::PropertyValue >& lObjArgs )
     114             :     throw ( lang::IllegalArgumentException,
     115             :             container::NoSuchElementException,
     116             :             io::IOException,
     117             :             uno::Exception,
     118             :             uno::RuntimeException, std::exception)
     119             : {
     120         155 :     if ( !xStorage.is() )
     121             :         throw lang::IllegalArgumentException( "No parent storage is provided!",
     122             :                                             static_cast< ::cppu::OWeakObject* >(this),
     123           0 :                                             1 );
     124             : 
     125         155 :     if ( sEntName.isEmpty() )
     126             :         throw lang::IllegalArgumentException( "Empty element name is provided!",
     127             :                                             static_cast< ::cppu::OWeakObject* >(this),
     128           1 :                                             2 );
     129             : 
     130         154 :     uno::Reference< container::XNameAccess > xNameAccess( xStorage, uno::UNO_QUERY );
     131         154 :     if ( !xNameAccess.is() )
     132           0 :         throw uno::RuntimeException(); //TODO
     133             : 
     134             :     // detect entry existence
     135         154 :     if ( !xNameAccess->hasByName( sEntName ) )
     136          14 :         throw container::NoSuchElementException();
     137             : 
     138         280 :     OUString aMediaType;
     139         280 :     OUString aEmbedFactory;
     140         140 :     if ( xStorage->isStorageElement( sEntName ) )
     141             :     {
     142             :         // the object must be based on storage
     143             :         uno::Reference< embed::XStorage > xSubStorage =
     144          54 :                 xStorage->openStorageElement( sEntName, embed::ElementModes::READ );
     145             : 
     146         108 :         uno::Reference< beans::XPropertySet > xPropSet( xSubStorage, uno::UNO_QUERY );
     147          54 :         if ( !xPropSet.is() )
     148           0 :             throw uno::RuntimeException();
     149             : 
     150             :         try {
     151          54 :             uno::Any aAny = xPropSet->getPropertyValue("MediaType");
     152          54 :             aAny >>= aMediaType;
     153             :         }
     154           0 :         catch ( const uno::Exception& )
     155             :         {
     156             :         }
     157             : 
     158             :         try {
     159          54 :             uno::Reference< lang::XComponent > xComp( xSubStorage, uno::UNO_QUERY );
     160          54 :             if ( xComp.is() )
     161          54 :                 xComp->dispose();
     162             :         }
     163           0 :         catch ( const uno::Exception& )
     164             :         {
     165          54 :         }
     166             :     }
     167             :     else
     168             :     {
     169             :         // the object must be based on stream
     170             :         // it means for now that this is an OLE object
     171             : 
     172             :         // the object will be created as embedded object
     173             :         // after it is loaded it can detect that it is a link
     174             : 
     175             :         uno::Reference< io::XStream > xSubStream =
     176          86 :                 xStorage->openStreamElement( sEntName, embed::ElementModes::READ );
     177             : 
     178         172 :         uno::Reference< beans::XPropertySet > xPropSet( xSubStream, uno::UNO_QUERY );
     179          86 :         if ( !xPropSet.is() )
     180           0 :             throw uno::RuntimeException();
     181             : 
     182             :         try {
     183          86 :             uno::Any aAny = xPropSet->getPropertyValue("MediaType");
     184          86 :             aAny >>= aMediaType;
     185          86 :             if ( aMediaType == "application/vnd.sun.star.oleobject" )
     186          86 :                 aEmbedFactory = "com.sun.star.embed.OLEEmbeddedObjectFactory";
     187             :         }
     188           0 :         catch ( const uno::Exception& )
     189             :         {
     190             :         }
     191             : 
     192             :         try {
     193          86 :             uno::Reference< lang::XComponent > xComp( xSubStream, uno::UNO_QUERY );
     194          86 :             if ( xComp.is() )
     195          86 :                 xComp->dispose();
     196             :         }
     197           0 :         catch ( const uno::Exception& )
     198             :         {
     199          86 :         }
     200             :     }
     201             : 
     202             :     OSL_ENSURE( !aMediaType.isEmpty(), "No media type is specified for the object!" );
     203         140 :     if ( !aMediaType.isEmpty() && aEmbedFactory.isEmpty() )
     204             :     {
     205          53 :         aEmbedFactory = m_aConfigHelper.GetFactoryNameByMediaType( aMediaType );
     206             : 
     207             :         // If no factory is found, fall back to the FileFormatVersion=6200 filter, Base only has that.
     208          53 :         if (aEmbedFactory.isEmpty() && aMediaType == MIMETYPE_OASIS_OPENDOCUMENT_DATABASE_ASCII)
     209           0 :             aEmbedFactory = m_aConfigHelper.GetFactoryNameByMediaType(MIMETYPE_VND_SUN_XML_BASE_ASCII);
     210             :     }
     211             : 
     212         140 :     if ( !aEmbedFactory.isEmpty() )
     213             :     {
     214         139 :         uno::Reference< uno::XInterface > xFact = m_xContext->getServiceManager()->createInstanceWithContext(aEmbedFactory, m_xContext);
     215             : 
     216         223 :         uno::Reference< embed::XEmbedObjectCreator > xEmbCreator( xFact, uno::UNO_QUERY );
     217         139 :         if ( xEmbCreator.is() )
     218          55 :             return xEmbCreator->createInstanceInitFromEntry( xStorage, sEntName, aMedDescr, lObjArgs );
     219             : 
     220         168 :         uno::Reference < embed::XEmbedObjectFactory > xEmbFact( xFact, uno::UNO_QUERY );
     221          84 :         if ( xEmbFact.is() )
     222          84 :             return xEmbFact->createInstanceUserInit( uno::Sequence< sal_Int8 >(), OUString(), xStorage, sEntName, embed::EntryInitModes::DEFAULT_INIT, aMedDescr, lObjArgs);
     223             :     }
     224             : 
     225             :     // the default object should be created, it will allow to store the contents on the next saving
     226         170 :     uno::Reference< uno::XInterface > xResult( static_cast< cppu::OWeakObject* >( new ODummyEmbeddedObject() ) );
     227         170 :     uno::Reference< embed::XEmbedPersist > xPersist( xResult, uno::UNO_QUERY_THROW );
     228          85 :     xPersist->setPersistentEntry( xStorage, sEntName, embed::EntryInitModes::DEFAULT_INIT, aMedDescr, lObjArgs );
     229         239 :     return xResult;
     230             : }
     231             : 
     232             : 
     233          21 : uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInstanceInitFromMediaDescriptor(
     234             :         const uno::Reference< embed::XStorage >& xStorage,
     235             :         const OUString& sEntName,
     236             :         const uno::Sequence< beans::PropertyValue >& aMediaDescr,
     237             :         const uno::Sequence< beans::PropertyValue >& lObjArgs )
     238             :     throw ( lang::IllegalArgumentException,
     239             :             io::IOException,
     240             :             uno::Exception,
     241             :             uno::RuntimeException, std::exception)
     242             : {
     243             :     // TODO: use lObjArgs
     244             : 
     245          21 :     if ( !xStorage.is() )
     246             :         throw lang::IllegalArgumentException( "No parent storage is provided!",
     247             :                                             static_cast< ::cppu::OWeakObject* >(this),
     248           0 :                                             1 );
     249             : 
     250          21 :     if ( sEntName.isEmpty() )
     251             :         throw lang::IllegalArgumentException( "Empty element name is provided!",
     252             :                                             static_cast< ::cppu::OWeakObject* >(this),
     253           0 :                                             2 );
     254             : 
     255          21 :     uno::Reference< uno::XInterface > xResult;
     256          42 :     uno::Sequence< beans::PropertyValue > aTempMedDescr( aMediaDescr );
     257             : 
     258             :     // check if there is FilterName
     259          42 :     OUString aFilterName = m_aConfigHelper.UpdateMediaDescriptorWithFilterName( aTempMedDescr, false );
     260             : 
     261          21 :     if ( !aFilterName.isEmpty() )
     262             :     {
     263             :         // the object can be loaded by one of the office application
     264             :         uno::Reference< embed::XEmbeddedObjectCreator > xOOoEmbCreator =
     265          17 :                             embed::OOoEmbeddedObjectFactory::create( m_xContext );
     266             : 
     267          47 :         xResult = xOOoEmbCreator->createInstanceInitFromMediaDescriptor( xStorage,
     268             :                                                                          sEntName,
     269             :                                                                          aTempMedDescr,
     270          47 :                                                                          lObjArgs );
     271             :     }
     272             :     else
     273             :     {
     274             :         // must be an OLE object
     275             : 
     276             :         // TODO: in future, when more object types are possible this place seems
     277             :         // to be a weak one, probably configuration must provide a type detection service
     278             :         // for every factory, so any file could go through services until it is recognized
     279             :         // or there is no more services
     280             :         // Or for example the typename can be used to detect object type if typedetection
     281             :         // was also extended.
     282             : 
     283             :         uno::Reference< embed::XEmbeddedObjectCreator > xOleEmbCreator =
     284           4 :                             embed::OLEEmbeddedObjectFactory::create( m_xContext );
     285             : 
     286           0 :         xResult = xOleEmbCreator->createInstanceInitFromMediaDescriptor( xStorage, sEntName, aTempMedDescr, lObjArgs );
     287             :     }
     288             : 
     289          26 :     return xResult;
     290             : }
     291             : 
     292             : 
     293           0 : uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInstanceUserInit(
     294             :         const uno::Sequence< sal_Int8 >& aClassID,
     295             :         const OUString& sClassName,
     296             :         const uno::Reference< embed::XStorage >& xStorage,
     297             :         const OUString& sEntName,
     298             :         sal_Int32 nEntryConnectionMode,
     299             :         const uno::Sequence< beans::PropertyValue >& aArgs,
     300             :         const uno::Sequence< beans::PropertyValue >& aObjectArgs )
     301             :     throw ( lang::IllegalArgumentException,
     302             :             io::IOException,
     303             :             uno::Exception,
     304             :             uno::RuntimeException, std::exception)
     305             : {
     306           0 :     uno::Reference< uno::XInterface > xResult;
     307             : 
     308           0 :     if ( !xStorage.is() )
     309             :         throw lang::IllegalArgumentException( "No parent storage is provided!",
     310             :                                             static_cast< ::cppu::OWeakObject* >(this),
     311           0 :                                             3 );
     312             : 
     313           0 :     if ( sEntName.isEmpty() )
     314             :         throw lang::IllegalArgumentException( "Empty element name is provided!",
     315             :                                             static_cast< ::cppu::OWeakObject* >(this),
     316           0 :                                             4 );
     317             : 
     318           0 :     OUString aEmbedFactory = m_aConfigHelper.GetFactoryNameByClassID( aClassID );
     319             :     uno::Reference< embed::XEmbedObjectFactory > xEmbFactory(
     320           0 :                         m_xContext->getServiceManager()->createInstanceWithContext(aEmbedFactory, m_xContext),
     321           0 :                         uno::UNO_QUERY );
     322           0 :     if ( !xEmbFactory.is() )
     323           0 :         throw uno::RuntimeException(); // TODO:
     324             : 
     325           0 :     return xEmbFactory->createInstanceUserInit( aClassID,
     326             :                                                 sClassName,
     327             :                                                 xStorage,
     328             :                                                 sEntName,
     329             :                                                 nEntryConnectionMode,
     330             :                                                 aArgs,
     331           0 :                                                 aObjectArgs );
     332             : }
     333             : 
     334             : 
     335           0 : uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInstanceLink(
     336             :                                             const uno::Reference< embed::XStorage >& xStorage,
     337             :                                             const OUString& sEntName,
     338             :                                             const uno::Sequence< beans::PropertyValue >& aMediaDescr,
     339             :                                             const uno::Sequence< beans::PropertyValue >& lObjArgs )
     340             :         throw ( lang::IllegalArgumentException,
     341             :                 io::IOException,
     342             :                 uno::Exception,
     343             :                 uno::RuntimeException, std::exception )
     344             : {
     345           0 :     uno::Reference< uno::XInterface > xResult;
     346             : 
     347           0 :     uno::Sequence< beans::PropertyValue > aTempMedDescr( aMediaDescr );
     348             : 
     349             :     // check if there is URL, URL must exist
     350           0 :     OUString aURL;
     351           0 :     for ( sal_Int32 nInd = 0; nInd < aTempMedDescr.getLength(); nInd++ )
     352           0 :         if ( aTempMedDescr[nInd].Name == "URL" )
     353           0 :             aTempMedDescr[nInd].Value >>= aURL;
     354             : 
     355           0 :     if ( aURL.isEmpty() )
     356             :         throw lang::IllegalArgumentException( "No URL for the link is provided!",
     357             :                                         static_cast< ::cppu::OWeakObject* >(this),
     358           0 :                                         3 );
     359             : 
     360           0 :     OUString aFilterName = m_aConfigHelper.UpdateMediaDescriptorWithFilterName( aTempMedDescr, false );
     361             : 
     362           0 :     if ( !aFilterName.isEmpty() )
     363             :     {
     364             :         // the object can be loaded by one of the office application
     365             :         uno::Reference< embed::XEmbeddedObjectCreator > xOOoLinkCreator =
     366           0 :                             embed::OOoEmbeddedObjectFactory::create( m_xContext );
     367             : 
     368           0 :         xResult = xOOoLinkCreator->createInstanceLink( xStorage,
     369             :                                                         sEntName,
     370             :                                                         aTempMedDescr,
     371           0 :                                                         lObjArgs );
     372             :     }
     373             :     else
     374             :     {
     375             :         // must be an OLE link
     376             : 
     377             :         // TODO: in future, when more object types are possible this place seems
     378             :         // to be a weak one, probably configuration must provide a type detection service
     379             :         // for every factory, so any file could go through services until it is recognized
     380             :         // or there is no more services
     381             :         // Or for example the typename can be used to detect object type if typedetection
     382             :         // was also extended.
     383             : 
     384           0 :         if ( !xStorage.is() )
     385             :             throw lang::IllegalArgumentException( "No parent storage is provided!",
     386             :                                                 static_cast< ::cppu::OWeakObject* >(this),
     387           0 :                                                 3 );
     388             : 
     389           0 :         if ( sEntName.isEmpty() )
     390             :             throw lang::IllegalArgumentException( "Empty element name is provided!",
     391             :                                                 static_cast< ::cppu::OWeakObject* >(this),
     392           0 :                                                 4 );
     393             : 
     394             :         uno::Reference< embed::XEmbeddedObjectCreator > xLinkCreator =
     395           0 :                             embed::OLEEmbeddedObjectFactory::create( m_xContext);
     396             : 
     397           0 :         xResult = xLinkCreator->createInstanceLink( xStorage, sEntName, aTempMedDescr, lObjArgs );
     398             :     }
     399             : 
     400           0 :     return xResult;
     401             : }
     402             : 
     403           1 : OUString SAL_CALL UNOEmbeddedObjectCreator::getImplementationName()
     404             :     throw ( uno::RuntimeException, std::exception )
     405             : {
     406           1 :     return impl_staticGetImplementationName();
     407             : }
     408             : 
     409           0 : sal_Bool SAL_CALL UNOEmbeddedObjectCreator::supportsService( const OUString& ServiceName )
     410             :     throw ( uno::RuntimeException, std::exception )
     411             : {
     412           0 :     return cppu::supportsService(this, ServiceName);
     413             : }
     414             : 
     415           1 : uno::Sequence< OUString > SAL_CALL UNOEmbeddedObjectCreator::getSupportedServiceNames()
     416             :     throw ( uno::RuntimeException, std::exception )
     417             : {
     418           1 :     return impl_staticGetSupportedServiceNames();
     419             : }
     420             : 
     421             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11