Version 3.6.0.4, tag libreoffice-3.6.0.4
[LibreOffice.git] / embeddedobj / source / general / xcreator.cxx
blob99c265ebe583f650ab91f8ad5fccf2105f026dc2
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include <com/sun/star/embed/ElementModes.hpp>
30 #include <com/sun/star/embed/EntryInitModes.hpp>
31 #include <com/sun/star/embed/XEmbedObjectFactory.hpp>
32 #include <com/sun/star/embed/XLinkFactory.hpp>
33 #include <com/sun/star/document/XTypeDetection.hpp>
34 #include <com/sun/star/beans/PropertyValue.hpp>
35 #include <com/sun/star/beans/XPropertySet.hpp>
36 #include <com/sun/star/container/XNameAccess.hpp>
37 #include <com/sun/star/lang/XComponent.hpp>
39 #include <rtl/logfile.hxx>
42 #include <xcreator.hxx>
43 #include <dummyobject.hxx>
46 using namespace ::com::sun::star;
49 //-------------------------------------------------------------------------
50 uno::Sequence< ::rtl::OUString > SAL_CALL UNOEmbeddedObjectCreator::impl_staticGetSupportedServiceNames()
52 uno::Sequence< ::rtl::OUString > aRet(2);
53 aRet[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.EmbeddedObjectCreator"));
54 aRet[1] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.embed.EmbeddedObjectCreator"));
55 return aRet;
58 //-------------------------------------------------------------------------
59 ::rtl::OUString SAL_CALL UNOEmbeddedObjectCreator::impl_staticGetImplementationName()
61 return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.embed.EmbeddedObjectCreator"));
64 //-------------------------------------------------------------------------
65 uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::impl_staticCreateSelfInstance(
66 const uno::Reference< lang::XMultiServiceFactory >& xServiceManager )
68 return uno::Reference< uno::XInterface >( *new UNOEmbeddedObjectCreator( xServiceManager ) );
71 //-------------------------------------------------------------------------
72 uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInstanceInitNew(
73 const uno::Sequence< sal_Int8 >& aClassID,
74 const ::rtl::OUString& aClassName,
75 const uno::Reference< embed::XStorage >& xStorage,
76 const ::rtl::OUString& sEntName,
77 const uno::Sequence< beans::PropertyValue >& lObjArgs )
78 throw ( lang::IllegalArgumentException,
79 io::IOException,
80 uno::Exception,
81 uno::RuntimeException)
83 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceInitNew" );
85 uno::Reference< uno::XInterface > xResult;
87 if ( !xStorage.is() )
88 throw lang::IllegalArgumentException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "No parent storage is provided!\n" )),
89 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
90 3 );
92 if ( sEntName.isEmpty() )
93 throw lang::IllegalArgumentException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Empty element name is provided!\n" )),
94 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
95 4 );
97 ::rtl::OUString aEmbedFactory = m_aConfigHelper.GetFactoryNameByClassID( aClassID );
98 if ( aEmbedFactory.isEmpty() )
100 // use system fallback
101 // TODO: in future users factories can be tested
102 aEmbedFactory = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.OLEEmbeddedObjectFactory" ));
105 uno::Reference < uno::XInterface > xFact( m_xFactory->createInstance( aEmbedFactory ) );
106 uno::Reference< embed::XEmbedObjectCreator > xEmbCreator( xFact, uno::UNO_QUERY );
107 if ( xEmbCreator.is() )
108 return xEmbCreator->createInstanceInitNew( aClassID, aClassName, xStorage, sEntName, lObjArgs );
110 uno::Reference < embed::XEmbedObjectFactory > xEmbFact( xFact, uno::UNO_QUERY );
111 if ( !xEmbFact.is() )
112 throw uno::RuntimeException();
113 return xEmbFact->createInstanceUserInit( aClassID, aClassName, xStorage, sEntName, embed::EntryInitModes::TRUNCATE_INIT, uno::Sequence < beans::PropertyValue >(), lObjArgs);
116 //-------------------------------------------------------------------------
117 uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInstanceInitFromEntry(
118 const uno::Reference< embed::XStorage >& xStorage,
119 const ::rtl::OUString& sEntName,
120 const uno::Sequence< beans::PropertyValue >& aMedDescr,
121 const uno::Sequence< beans::PropertyValue >& lObjArgs )
122 throw ( lang::IllegalArgumentException,
123 container::NoSuchElementException,
124 io::IOException,
125 uno::Exception,
126 uno::RuntimeException)
128 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceInitFromEntry" );
130 if ( !xStorage.is() )
131 throw lang::IllegalArgumentException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "No parent storage is provided!\n" )),
132 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
133 1 );
135 if ( sEntName.isEmpty() )
136 throw lang::IllegalArgumentException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Empty element name is provided!\n" )),
137 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
138 2 );
140 uno::Reference< container::XNameAccess > xNameAccess( xStorage, uno::UNO_QUERY );
141 if ( !xNameAccess.is() )
142 throw uno::RuntimeException(); //TODO
144 // detect entry existence
145 if ( !xNameAccess->hasByName( sEntName ) )
146 throw container::NoSuchElementException();
148 ::rtl::OUString aMediaType;
149 ::rtl::OUString aEmbedFactory;
150 if ( xStorage->isStorageElement( sEntName ) )
152 // the object must be based on storage
153 uno::Reference< embed::XStorage > xSubStorage =
154 xStorage->openStorageElement( sEntName, embed::ElementModes::READ );
156 uno::Reference< beans::XPropertySet > xPropSet( xSubStorage, uno::UNO_QUERY );
157 if ( !xPropSet.is() )
158 throw uno::RuntimeException();
160 try {
161 uno::Any aAny = xPropSet->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ));
162 aAny >>= aMediaType;
164 catch ( const uno::Exception& )
168 try {
169 uno::Reference< lang::XComponent > xComp( xSubStorage, uno::UNO_QUERY );
170 if ( xComp.is() )
171 xComp->dispose();
173 catch ( const uno::Exception& )
177 else
179 // the object must be based on stream
180 // it means for now that this is an OLE object
182 // the object will be created as embedded object
183 // after it is loaded it can detect that it is a link
185 uno::Reference< io::XStream > xSubStream =
186 xStorage->openStreamElement( sEntName, embed::ElementModes::READ );
188 uno::Reference< beans::XPropertySet > xPropSet( xSubStream, uno::UNO_QUERY );
189 if ( !xPropSet.is() )
190 throw uno::RuntimeException();
192 try {
193 uno::Any aAny = xPropSet->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ));
194 aAny >>= aMediaType;
195 if ( aMediaType == "application/vnd.sun.star.oleobject" )
196 aEmbedFactory = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.OLEEmbeddedObjectFactory" ) );
198 catch ( const uno::Exception& )
202 try {
203 uno::Reference< lang::XComponent > xComp( xSubStream, uno::UNO_QUERY );
204 if ( xComp.is() )
205 xComp->dispose();
207 catch ( const uno::Exception& )
212 OSL_ENSURE( !aMediaType.isEmpty(), "No media type is specified for the object!" );
213 if ( !aMediaType.isEmpty() && aEmbedFactory.isEmpty() )
214 aEmbedFactory = m_aConfigHelper.GetFactoryNameByMediaType( aMediaType );
216 if ( !aEmbedFactory.isEmpty() )
218 uno::Reference< uno::XInterface > xFact = m_xFactory->createInstance( aEmbedFactory );
220 uno::Reference< embed::XEmbedObjectCreator > xEmbCreator( xFact, uno::UNO_QUERY );
221 if ( xEmbCreator.is() )
222 return xEmbCreator->createInstanceInitFromEntry( xStorage, sEntName, aMedDescr, lObjArgs );
224 uno::Reference < embed::XEmbedObjectFactory > xEmbFact( xFact, uno::UNO_QUERY );
225 if ( xEmbFact.is() )
226 return xEmbFact->createInstanceUserInit( uno::Sequence< sal_Int8 >(), ::rtl::OUString(), xStorage, sEntName, embed::EntryInitModes::DEFAULT_INIT, aMedDescr, lObjArgs);
229 // the default object should be created, it will allow to store the contents on the next saving
230 uno::Reference< uno::XInterface > xResult( static_cast< cppu::OWeakObject* >( new ODummyEmbeddedObject() ) );
231 uno::Reference< embed::XEmbedPersist > xPersist( xResult, uno::UNO_QUERY_THROW );
232 xPersist->setPersistentEntry( xStorage, sEntName, embed::EntryInitModes::DEFAULT_INIT, aMedDescr, lObjArgs );
233 return xResult;
236 //-------------------------------------------------------------------------
237 uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInstanceInitFromMediaDescriptor(
238 const uno::Reference< embed::XStorage >& xStorage,
239 const ::rtl::OUString& sEntName,
240 const uno::Sequence< beans::PropertyValue >& aMediaDescr,
241 const uno::Sequence< beans::PropertyValue >& lObjArgs )
242 throw ( lang::IllegalArgumentException,
243 io::IOException,
244 uno::Exception,
245 uno::RuntimeException)
247 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceInitFromMediaDescriptor" );
249 // TODO: use lObjArgs
251 if ( !xStorage.is() )
252 throw lang::IllegalArgumentException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "No parent storage is provided!\n" )),
253 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
254 1 );
256 if ( sEntName.isEmpty() )
257 throw lang::IllegalArgumentException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Empty element name is provided!\n" )),
258 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
259 2 );
261 uno::Reference< uno::XInterface > xResult;
262 uno::Sequence< beans::PropertyValue > aTempMedDescr( aMediaDescr );
264 // check if there is FilterName
265 ::rtl::OUString aFilterName = m_aConfigHelper.UpdateMediaDescriptorWithFilterName( aTempMedDescr, sal_False );
267 if ( !aFilterName.isEmpty() )
269 // the object can be loaded by one of the office application
270 uno::Reference< embed::XEmbedObjectCreator > xOOoEmbCreator(
271 m_xFactory->createInstance(
272 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.OOoEmbeddedObjectFactory" ) )),
273 uno::UNO_QUERY );
274 if ( !xOOoEmbCreator.is() )
275 throw uno::RuntimeException(); // TODO:
277 xResult = xOOoEmbCreator->createInstanceInitFromMediaDescriptor( xStorage,
278 sEntName,
279 aTempMedDescr,
280 lObjArgs );
282 else
284 // must be an OLE object
286 // TODO: in future, when more object types are possible this place seems
287 // to be a weak one, probably configuration must provide a type detection service
288 // for every factory, so any file could go through services until it is recognized
289 // or there is no more services
290 // Or for example the typename can be used to detect object type if typedetection
291 // was also extended.
293 uno::Reference< embed::XEmbedObjectCreator > xOleEmbCreator(
294 m_xFactory->createInstance(
295 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.OLEEmbeddedObjectFactory" ) )),
296 uno::UNO_QUERY );
297 if ( !xOleEmbCreator.is() )
298 throw uno::RuntimeException(); // TODO:
300 xResult = xOleEmbCreator->createInstanceInitFromMediaDescriptor( xStorage, sEntName, aTempMedDescr, lObjArgs );
303 return xResult;
306 //-------------------------------------------------------------------------
307 uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInstanceUserInit(
308 const uno::Sequence< sal_Int8 >& aClassID,
309 const ::rtl::OUString& sClassName,
310 const uno::Reference< embed::XStorage >& xStorage,
311 const ::rtl::OUString& sEntName,
312 sal_Int32 nEntryConnectionMode,
313 const uno::Sequence< beans::PropertyValue >& aArgs,
314 const uno::Sequence< beans::PropertyValue >& aObjectArgs )
315 throw ( lang::IllegalArgumentException,
316 io::IOException,
317 uno::Exception,
318 uno::RuntimeException)
320 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceUserInit" );
322 uno::Reference< uno::XInterface > xResult;
324 if ( !xStorage.is() )
325 throw lang::IllegalArgumentException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "No parent storage is provided!\n" )),
326 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
327 3 );
329 if ( sEntName.isEmpty() )
330 throw lang::IllegalArgumentException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Empty element name is provided!\n" )),
331 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
332 4 );
334 ::rtl::OUString aEmbedFactory = m_aConfigHelper.GetFactoryNameByClassID( aClassID );
335 uno::Reference< embed::XEmbedObjectFactory > xEmbFactory(
336 m_xFactory->createInstance( aEmbedFactory ),
337 uno::UNO_QUERY );
338 if ( !xEmbFactory.is() )
339 throw uno::RuntimeException(); // TODO:
341 return xEmbFactory->createInstanceUserInit( aClassID,
342 sClassName,
343 xStorage,
344 sEntName,
345 nEntryConnectionMode,
346 aArgs,
347 aObjectArgs );
350 //-------------------------------------------------------------------------
351 uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInstanceLink(
352 const uno::Reference< embed::XStorage >& xStorage,
353 const ::rtl::OUString& sEntName,
354 const uno::Sequence< beans::PropertyValue >& aMediaDescr,
355 const uno::Sequence< beans::PropertyValue >& lObjArgs )
356 throw ( lang::IllegalArgumentException,
357 io::IOException,
358 uno::Exception,
359 uno::RuntimeException )
361 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceLink" );
363 uno::Reference< uno::XInterface > xResult;
365 uno::Sequence< beans::PropertyValue > aTempMedDescr( aMediaDescr );
367 // check if there is URL, URL must exist
368 ::rtl::OUString aURL;
369 for ( sal_Int32 nInd = 0; nInd < aTempMedDescr.getLength(); nInd++ )
370 if ( aTempMedDescr[nInd].Name == "URL" )
371 aTempMedDescr[nInd].Value >>= aURL;
373 if ( aURL.isEmpty() )
374 throw lang::IllegalArgumentException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "No URL for the link is provided!\n" )),
375 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
376 3 );
378 ::rtl::OUString aFilterName = m_aConfigHelper.UpdateMediaDescriptorWithFilterName( aTempMedDescr, sal_False );
380 if ( !aFilterName.isEmpty() )
382 // the object can be loaded by one of the office application
383 uno::Reference< embed::XLinkCreator > xOOoLinkCreator(
384 m_xFactory->createInstance(
385 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.OOoEmbeddedObjectFactory" ) )),
386 uno::UNO_QUERY );
387 if ( !xOOoLinkCreator.is() )
388 throw uno::RuntimeException(); // TODO:
390 xResult = xOOoLinkCreator->createInstanceLink( xStorage,
391 sEntName,
392 aTempMedDescr,
393 lObjArgs );
395 else
397 // must be an OLE link
399 // TODO: in future, when more object types are possible this place seems
400 // to be a weak one, probably configuration must provide a type detection service
401 // for every factory, so any file could go through services until it is recognized
402 // or there is no more services
403 // Or for example the typename can be used to detect object type if typedetection
404 // was also extended.
406 if ( !xStorage.is() )
407 throw lang::IllegalArgumentException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "No parent storage is provided!\n" )),
408 uno::Reference< uno::XInterface >(
409 static_cast< ::cppu::OWeakObject* >(this) ),
410 3 );
412 if ( sEntName.isEmpty() )
413 throw lang::IllegalArgumentException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Empty element name is provided!\n" )),
414 uno::Reference< uno::XInterface >(
415 static_cast< ::cppu::OWeakObject* >(this) ),
416 4 );
418 uno::Reference< embed::XLinkCreator > xLinkCreator(
419 m_xFactory->createInstance(
420 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.OLEEmbeddedObjectFactory" ) )),
421 uno::UNO_QUERY );
422 if ( !xLinkCreator.is() )
423 throw uno::RuntimeException(); // TODO:
425 xResult = xLinkCreator->createInstanceLink( xStorage, sEntName, aTempMedDescr, lObjArgs );
428 return xResult;
431 //-------------------------------------------------------------------------
432 uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInstanceLinkUserInit(
433 const uno::Sequence< sal_Int8 >& aClassID,
434 const ::rtl::OUString& aClassName,
435 const uno::Reference< embed::XStorage >& xStorage,
436 const ::rtl::OUString& sEntName,
437 const uno::Sequence< beans::PropertyValue >& lArguments,
438 const uno::Sequence< beans::PropertyValue >& lObjArgs )
439 throw ( lang::IllegalArgumentException,
440 io::IOException,
441 uno::Exception,
442 uno::RuntimeException )
444 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceLinkUserInit" );
446 uno::Reference< uno::XInterface > xResult;
448 ::rtl::OUString aEmbedFactory = m_aConfigHelper.GetFactoryNameByClassID( aClassID );
449 uno::Reference< embed::XLinkFactory > xLinkFactory(
450 m_xFactory->createInstance( aEmbedFactory ),
451 uno::UNO_QUERY );
452 if ( !xLinkFactory.is() )
453 throw uno::RuntimeException(); // TODO:
455 return xLinkFactory->createInstanceLinkUserInit( aClassID,
456 aClassName,
457 xStorage,
458 sEntName,
459 lArguments,
460 lObjArgs );
464 //-------------------------------------------------------------------------
465 ::rtl::OUString SAL_CALL UNOEmbeddedObjectCreator::getImplementationName()
466 throw ( uno::RuntimeException )
468 return impl_staticGetImplementationName();
471 //-------------------------------------------------------------------------
472 sal_Bool SAL_CALL UNOEmbeddedObjectCreator::supportsService( const ::rtl::OUString& ServiceName )
473 throw ( uno::RuntimeException )
475 uno::Sequence< ::rtl::OUString > aSeq = impl_staticGetSupportedServiceNames();
477 for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
478 if ( ServiceName.compareTo( aSeq[nInd] ) == 0 )
479 return sal_True;
481 return sal_False;
484 //-------------------------------------------------------------------------
485 uno::Sequence< ::rtl::OUString > SAL_CALL UNOEmbeddedObjectCreator::getSupportedServiceNames()
486 throw ( uno::RuntimeException )
488 return impl_staticGetSupportedServiceNames();
491 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */