1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_embeddedobj.hxx" 26 #include <com/sun/star/embed/ElementModes.hpp> 27 #include <com/sun/star/embed/EntryInitModes.hpp> 28 #include <com/sun/star/embed/XEmbedObjectFactory.hpp> 29 #include <com/sun/star/embed/XLinkFactory.hpp> 30 #include <com/sun/star/document/XTypeDetection.hpp> 31 #include <com/sun/star/beans/PropertyValue.hpp> 32 #include <com/sun/star/beans/XPropertySet.hpp> 33 #include <com/sun/star/container/XNameAccess.hpp> 34 #include <com/sun/star/lang/XComponent.hpp> 35 36 #include <rtl/logfile.hxx> 37 38 39 #include <xcreator.hxx> 40 #include <dummyobject.hxx> 41 42 43 using namespace ::com::sun::star; 44 45 46 //------------------------------------------------------------------------- 47 uno::Sequence< ::rtl::OUString > SAL_CALL UNOEmbeddedObjectCreator::impl_staticGetSupportedServiceNames() 48 { 49 uno::Sequence< ::rtl::OUString > aRet(2); 50 aRet[0] = ::rtl::OUString::createFromAscii("com.sun.star.embed.EmbeddedObjectCreator"); 51 aRet[1] = ::rtl::OUString::createFromAscii("com.sun.star.comp.embed.EmbeddedObjectCreator"); 52 return aRet; 53 } 54 55 //------------------------------------------------------------------------- 56 ::rtl::OUString SAL_CALL UNOEmbeddedObjectCreator::impl_staticGetImplementationName() 57 { 58 return ::rtl::OUString::createFromAscii("com.sun.star.comp.embed.EmbeddedObjectCreator"); 59 } 60 61 //------------------------------------------------------------------------- 62 uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::impl_staticCreateSelfInstance( 63 const uno::Reference< lang::XMultiServiceFactory >& xServiceManager ) 64 { 65 return uno::Reference< uno::XInterface >( *new UNOEmbeddedObjectCreator( xServiceManager ) ); 66 } 67 68 //------------------------------------------------------------------------- 69 uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInstanceInitNew( 70 const uno::Sequence< sal_Int8 >& aClassID, 71 const ::rtl::OUString& aClassName, 72 const uno::Reference< embed::XStorage >& xStorage, 73 const ::rtl::OUString& sEntName, 74 const uno::Sequence< beans::PropertyValue >& lObjArgs ) 75 throw ( lang::IllegalArgumentException, 76 io::IOException, 77 uno::Exception, 78 uno::RuntimeException) 79 { 80 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceInitNew" ); 81 82 uno::Reference< uno::XInterface > xResult; 83 84 if ( !xStorage.is() ) 85 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ), 86 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ), 87 3 ); 88 89 if ( !sEntName.getLength() ) 90 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ), 91 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ), 92 4 ); 93 94 ::rtl::OUString aEmbedFactory = m_aConfigHelper.GetFactoryNameByClassID( aClassID ); 95 if ( !aEmbedFactory.getLength() ) 96 { 97 // use system fallback 98 // TODO: in future users factories can be tested 99 aEmbedFactory = ::rtl::OUString::createFromAscii( "com.sun.star.embed.OLEEmbeddedObjectFactory" ); 100 } 101 102 uno::Reference < uno::XInterface > xFact( m_xFactory->createInstance( aEmbedFactory ) ); 103 uno::Reference< embed::XEmbedObjectCreator > xEmbCreator( xFact, uno::UNO_QUERY ); 104 if ( xEmbCreator.is() ) 105 return xEmbCreator->createInstanceInitNew( aClassID, aClassName, xStorage, sEntName, lObjArgs ); 106 107 uno::Reference < embed::XEmbedObjectFactory > xEmbFact( xFact, uno::UNO_QUERY ); 108 if ( !xEmbFact.is() ) 109 throw uno::RuntimeException(); 110 return xEmbFact->createInstanceUserInit( aClassID, aClassName, xStorage, sEntName, embed::EntryInitModes::TRUNCATE_INIT, uno::Sequence < beans::PropertyValue >(), lObjArgs); 111 } 112 113 //------------------------------------------------------------------------- 114 uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInstanceInitFromEntry( 115 const uno::Reference< embed::XStorage >& xStorage, 116 const ::rtl::OUString& sEntName, 117 const uno::Sequence< beans::PropertyValue >& aMedDescr, 118 const uno::Sequence< beans::PropertyValue >& lObjArgs ) 119 throw ( lang::IllegalArgumentException, 120 container::NoSuchElementException, 121 io::IOException, 122 uno::Exception, 123 uno::RuntimeException) 124 { 125 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceInitFromEntry" ); 126 127 if ( !xStorage.is() ) 128 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ), 129 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ), 130 1 ); 131 132 if ( !sEntName.getLength() ) 133 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ), 134 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ), 135 2 ); 136 137 uno::Reference< container::XNameAccess > xNameAccess( xStorage, uno::UNO_QUERY ); 138 if ( !xNameAccess.is() ) 139 throw uno::RuntimeException(); //TODO 140 141 // detect entry existence 142 if ( !xNameAccess->hasByName( sEntName ) ) 143 throw container::NoSuchElementException(); 144 145 ::rtl::OUString aMediaType; 146 ::rtl::OUString aEmbedFactory; 147 if ( xStorage->isStorageElement( sEntName ) ) 148 { 149 // the object must be based on storage 150 uno::Reference< embed::XStorage > xSubStorage = 151 xStorage->openStorageElement( sEntName, embed::ElementModes::READ ); 152 153 uno::Reference< beans::XPropertySet > xPropSet( xSubStorage, uno::UNO_QUERY ); 154 if ( !xPropSet.is() ) 155 throw uno::RuntimeException(); 156 157 try { 158 uno::Any aAny = xPropSet->getPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ) ); 159 aAny >>= aMediaType; 160 } 161 catch ( uno::Exception& ) 162 { 163 } 164 165 try { 166 uno::Reference< lang::XComponent > xComp( xSubStorage, uno::UNO_QUERY ); 167 if ( xComp.is() ) 168 xComp->dispose(); 169 } 170 catch ( uno::Exception& ) 171 { 172 } 173 } 174 else 175 { 176 // the object must be based on stream 177 // it means for now that this is an OLE object 178 179 // the object will be created as embedded object 180 // after it is loaded it can detect that it is a link 181 182 uno::Reference< io::XStream > xSubStream = 183 xStorage->openStreamElement( sEntName, embed::ElementModes::READ ); 184 185 uno::Reference< beans::XPropertySet > xPropSet( xSubStream, uno::UNO_QUERY ); 186 if ( !xPropSet.is() ) 187 throw uno::RuntimeException(); 188 189 try { 190 uno::Any aAny = xPropSet->getPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ) ); 191 aAny >>= aMediaType; 192 if ( aMediaType.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/vnd.sun.star.oleobject" ) ) ) ) 193 aEmbedFactory = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.OLEEmbeddedObjectFactory" ) ); 194 } 195 catch ( uno::Exception& ) 196 { 197 } 198 199 try { 200 uno::Reference< lang::XComponent > xComp( xSubStream, uno::UNO_QUERY ); 201 if ( xComp.is() ) 202 xComp->dispose(); 203 } 204 catch ( uno::Exception& ) 205 { 206 } 207 } 208 209 OSL_ENSURE( aMediaType.getLength(), "No media type is specified for the object!" ); 210 if ( aMediaType.getLength() && !aEmbedFactory.getLength() ) 211 aEmbedFactory = m_aConfigHelper.GetFactoryNameByMediaType( aMediaType ); 212 213 if ( aEmbedFactory.getLength() ) 214 { 215 uno::Reference< uno::XInterface > xFact = m_xFactory->createInstance( aEmbedFactory ); 216 217 uno::Reference< embed::XEmbedObjectCreator > xEmbCreator( xFact, uno::UNO_QUERY ); 218 if ( xEmbCreator.is() ) 219 return xEmbCreator->createInstanceInitFromEntry( xStorage, sEntName, aMedDescr, lObjArgs ); 220 221 uno::Reference < embed::XEmbedObjectFactory > xEmbFact( xFact, uno::UNO_QUERY ); 222 if ( xEmbFact.is() ) 223 return xEmbFact->createInstanceUserInit( uno::Sequence< sal_Int8 >(), ::rtl::OUString(), xStorage, sEntName, embed::EntryInitModes::DEFAULT_INIT, aMedDescr, lObjArgs); 224 } 225 226 // the default object should be created, it will allow to store the contents on the next saving 227 uno::Reference< uno::XInterface > xResult( static_cast< cppu::OWeakObject* >( new ODummyEmbeddedObject() ) ); 228 uno::Reference< embed::XEmbedPersist > xPersist( xResult, uno::UNO_QUERY_THROW ); 229 xPersist->setPersistentEntry( xStorage, sEntName, embed::EntryInitModes::DEFAULT_INIT, aMedDescr, lObjArgs ); 230 return xResult; 231 } 232 233 //------------------------------------------------------------------------- 234 uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInstanceInitFromMediaDescriptor( 235 const uno::Reference< embed::XStorage >& xStorage, 236 const ::rtl::OUString& sEntName, 237 const uno::Sequence< beans::PropertyValue >& aMediaDescr, 238 const uno::Sequence< beans::PropertyValue >& lObjArgs ) 239 throw ( lang::IllegalArgumentException, 240 io::IOException, 241 uno::Exception, 242 uno::RuntimeException) 243 { 244 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceInitFromMediaDescriptor" ); 245 246 // TODO: use lObjArgs 247 248 if ( !xStorage.is() ) 249 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ), 250 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ), 251 1 ); 252 253 if ( !sEntName.getLength() ) 254 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ), 255 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ), 256 2 ); 257 258 uno::Reference< uno::XInterface > xResult; 259 uno::Sequence< beans::PropertyValue > aTempMedDescr( aMediaDescr ); 260 261 // check if there is FilterName 262 ::rtl::OUString aFilterName = m_aConfigHelper.UpdateMediaDescriptorWithFilterName( aTempMedDescr, sal_False ); 263 264 if ( aFilterName.getLength() ) 265 { 266 // the object can be loaded by one of the office application 267 uno::Reference< embed::XEmbedObjectCreator > xOOoEmbCreator( 268 m_xFactory->createInstance( 269 ::rtl::OUString::createFromAscii( "com.sun.star.embed.OOoEmbeddedObjectFactory" ) ), 270 uno::UNO_QUERY ); 271 if ( !xOOoEmbCreator.is() ) 272 throw uno::RuntimeException(); // TODO: 273 274 xResult = xOOoEmbCreator->createInstanceInitFromMediaDescriptor( xStorage, 275 sEntName, 276 aTempMedDescr, 277 lObjArgs ); 278 } 279 else 280 { 281 // must be an OLE object 282 283 // TODO: in future, when more object types are possible this place seems 284 // to be a weak one, probably configuration must provide a type detection service 285 // for every factory, so any file could go through services until it is recognized 286 // or there is no more services 287 // Or for example the typename can be used to detect object type if typedetection 288 // was also extended. 289 290 uno::Reference< embed::XEmbedObjectCreator > xOleEmbCreator( 291 m_xFactory->createInstance( 292 ::rtl::OUString::createFromAscii( "com.sun.star.embed.OLEEmbeddedObjectFactory" ) ), 293 uno::UNO_QUERY ); 294 if ( !xOleEmbCreator.is() ) 295 throw uno::RuntimeException(); // TODO: 296 297 xResult = xOleEmbCreator->createInstanceInitFromMediaDescriptor( xStorage, sEntName, aTempMedDescr, lObjArgs ); 298 } 299 300 return xResult; 301 } 302 303 //------------------------------------------------------------------------- 304 uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInstanceUserInit( 305 const uno::Sequence< sal_Int8 >& aClassID, 306 const ::rtl::OUString& sClassName, 307 const uno::Reference< embed::XStorage >& xStorage, 308 const ::rtl::OUString& sEntName, 309 sal_Int32 nEntryConnectionMode, 310 const uno::Sequence< beans::PropertyValue >& aArgs, 311 const uno::Sequence< beans::PropertyValue >& aObjectArgs ) 312 throw ( lang::IllegalArgumentException, 313 io::IOException, 314 uno::Exception, 315 uno::RuntimeException) 316 { 317 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceUserInit" ); 318 319 uno::Reference< uno::XInterface > xResult; 320 321 if ( !xStorage.is() ) 322 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ), 323 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ), 324 3 ); 325 326 if ( !sEntName.getLength() ) 327 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ), 328 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ), 329 4 ); 330 331 ::rtl::OUString aEmbedFactory = m_aConfigHelper.GetFactoryNameByClassID( aClassID ); 332 uno::Reference< embed::XEmbedObjectFactory > xEmbFactory( 333 m_xFactory->createInstance( aEmbedFactory ), 334 uno::UNO_QUERY ); 335 if ( !xEmbFactory.is() ) 336 throw uno::RuntimeException(); // TODO: 337 338 return xEmbFactory->createInstanceUserInit( aClassID, 339 sClassName, 340 xStorage, 341 sEntName, 342 nEntryConnectionMode, 343 aArgs, 344 aObjectArgs ); 345 } 346 347 //------------------------------------------------------------------------- 348 uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInstanceLink( 349 const uno::Reference< embed::XStorage >& xStorage, 350 const ::rtl::OUString& sEntName, 351 const uno::Sequence< beans::PropertyValue >& aMediaDescr, 352 const uno::Sequence< beans::PropertyValue >& lObjArgs ) 353 throw ( lang::IllegalArgumentException, 354 io::IOException, 355 uno::Exception, 356 uno::RuntimeException ) 357 { 358 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceLink" ); 359 360 uno::Reference< uno::XInterface > xResult; 361 362 uno::Sequence< beans::PropertyValue > aTempMedDescr( aMediaDescr ); 363 364 // check if there is URL, URL must exist 365 ::rtl::OUString aURL; 366 for ( sal_Int32 nInd = 0; nInd < aTempMedDescr.getLength(); nInd++ ) 367 if ( aTempMedDescr[nInd].Name.equalsAscii( "URL" ) ) 368 aTempMedDescr[nInd].Value >>= aURL; 369 370 if ( !aURL.getLength() ) 371 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No URL for the link is provided!\n" ), 372 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ), 373 3 ); 374 375 ::rtl::OUString aFilterName = m_aConfigHelper.UpdateMediaDescriptorWithFilterName( aTempMedDescr, sal_False ); 376 377 if ( aFilterName.getLength() ) 378 { 379 // the object can be loaded by one of the office application 380 uno::Reference< embed::XLinkCreator > xOOoLinkCreator( 381 m_xFactory->createInstance( 382 ::rtl::OUString::createFromAscii( "com.sun.star.embed.OOoEmbeddedObjectFactory" ) ), 383 uno::UNO_QUERY ); 384 if ( !xOOoLinkCreator.is() ) 385 throw uno::RuntimeException(); // TODO: 386 387 xResult = xOOoLinkCreator->createInstanceLink( xStorage, 388 sEntName, 389 aTempMedDescr, 390 lObjArgs ); 391 } 392 else 393 { 394 // must be an OLE link 395 396 // TODO: in future, when more object types are possible this place seems 397 // to be a weak one, probably configuration must provide a type detection service 398 // for every factory, so any file could go through services until it is recognized 399 // or there is no more services 400 // Or for example the typename can be used to detect object type if typedetection 401 // was also extended. 402 403 if ( !xStorage.is() ) 404 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ), 405 uno::Reference< uno::XInterface >( 406 static_cast< ::cppu::OWeakObject* >(this) ), 407 3 ); 408 409 if ( !sEntName.getLength() ) 410 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ), 411 uno::Reference< uno::XInterface >( 412 static_cast< ::cppu::OWeakObject* >(this) ), 413 4 ); 414 415 uno::Reference< embed::XLinkCreator > xLinkCreator( 416 m_xFactory->createInstance( 417 ::rtl::OUString::createFromAscii( "com.sun.star.embed.OLEEmbeddedObjectFactory" ) ), 418 uno::UNO_QUERY ); 419 if ( !xLinkCreator.is() ) 420 throw uno::RuntimeException(); // TODO: 421 422 xResult = xLinkCreator->createInstanceLink( xStorage, sEntName, aTempMedDescr, lObjArgs ); 423 } 424 425 return xResult; 426 } 427 428 //------------------------------------------------------------------------- 429 uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInstanceLinkUserInit( 430 const uno::Sequence< sal_Int8 >& aClassID, 431 const ::rtl::OUString& aClassName, 432 const uno::Reference< embed::XStorage >& xStorage, 433 const ::rtl::OUString& sEntName, 434 const uno::Sequence< beans::PropertyValue >& lArguments, 435 const uno::Sequence< beans::PropertyValue >& lObjArgs ) 436 throw ( lang::IllegalArgumentException, 437 io::IOException, 438 uno::Exception, 439 uno::RuntimeException ) 440 { 441 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceLinkUserInit" ); 442 443 uno::Reference< uno::XInterface > xResult; 444 445 ::rtl::OUString aEmbedFactory = m_aConfigHelper.GetFactoryNameByClassID( aClassID ); 446 uno::Reference< embed::XLinkFactory > xLinkFactory( 447 m_xFactory->createInstance( aEmbedFactory ), 448 uno::UNO_QUERY ); 449 if ( !xLinkFactory.is() ) 450 throw uno::RuntimeException(); // TODO: 451 452 return xLinkFactory->createInstanceLinkUserInit( aClassID, 453 aClassName, 454 xStorage, 455 sEntName, 456 lArguments, 457 lObjArgs ); 458 459 } 460 461 //------------------------------------------------------------------------- 462 ::rtl::OUString SAL_CALL UNOEmbeddedObjectCreator::getImplementationName() 463 throw ( uno::RuntimeException ) 464 { 465 return impl_staticGetImplementationName(); 466 } 467 468 //------------------------------------------------------------------------- 469 sal_Bool SAL_CALL UNOEmbeddedObjectCreator::supportsService( const ::rtl::OUString& ServiceName ) 470 throw ( uno::RuntimeException ) 471 { 472 uno::Sequence< ::rtl::OUString > aSeq = impl_staticGetSupportedServiceNames(); 473 474 for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ ) 475 if ( ServiceName.compareTo( aSeq[nInd] ) == 0 ) 476 return sal_True; 477 478 return sal_False; 479 } 480 481 //------------------------------------------------------------------------- 482 uno::Sequence< ::rtl::OUString > SAL_CALL UNOEmbeddedObjectCreator::getSupportedServiceNames() 483 throw ( uno::RuntimeException ) 484 { 485 return impl_staticGetSupportedServiceNames(); 486 } 487 488