1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xcreator.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_embeddedobj.hxx"
33 #include <com/sun/star/embed/ElementModes.hpp>
34 #include <com/sun/star/embed/EntryInitModes.hpp>
35 #include <com/sun/star/embed/XEmbedObjectFactory.hpp>
36 #include <com/sun/star/embed/XLinkFactory.hpp>
37 #include <com/sun/star/document/XTypeDetection.hpp>
38 #include <com/sun/star/beans/PropertyValue.hpp>
39 #include <com/sun/star/beans/XPropertySet.hpp>
40 #include <com/sun/star/container/XNameAccess.hpp>
41 #include <com/sun/star/lang/XComponent.hpp>
43 #include <rtl/logfile.hxx>
46 #include <xcreator.hxx>
47 #include <dummyobject.hxx>
50 using namespace ::com::sun::star
;
53 //-------------------------------------------------------------------------
54 uno::Sequence
< ::rtl::OUString
> SAL_CALL
UNOEmbeddedObjectCreator::impl_staticGetSupportedServiceNames()
56 uno::Sequence
< ::rtl::OUString
> aRet(2);
57 aRet
[0] = ::rtl::OUString::createFromAscii("com.sun.star.embed.EmbeddedObjectCreator");
58 aRet
[1] = ::rtl::OUString::createFromAscii("com.sun.star.comp.embed.EmbeddedObjectCreator");
62 //-------------------------------------------------------------------------
63 ::rtl::OUString SAL_CALL
UNOEmbeddedObjectCreator::impl_staticGetImplementationName()
65 return ::rtl::OUString::createFromAscii("com.sun.star.comp.embed.EmbeddedObjectCreator");
68 //-------------------------------------------------------------------------
69 uno::Reference
< uno::XInterface
> SAL_CALL
UNOEmbeddedObjectCreator::impl_staticCreateSelfInstance(
70 const uno::Reference
< lang::XMultiServiceFactory
>& xServiceManager
)
72 return uno::Reference
< uno::XInterface
>( *new UNOEmbeddedObjectCreator( xServiceManager
) );
75 //-------------------------------------------------------------------------
76 uno::Reference
< uno::XInterface
> SAL_CALL
UNOEmbeddedObjectCreator::createInstanceInitNew(
77 const uno::Sequence
< sal_Int8
>& aClassID
,
78 const ::rtl::OUString
& aClassName
,
79 const uno::Reference
< embed::XStorage
>& xStorage
,
80 const ::rtl::OUString
& sEntName
,
81 const uno::Sequence
< beans::PropertyValue
>& lObjArgs
)
82 throw ( lang::IllegalArgumentException
,
85 uno::RuntimeException
)
87 RTL_LOGFILE_CONTEXT( aLog
, "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceInitNew" );
89 uno::Reference
< uno::XInterface
> xResult
;
92 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ),
93 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ),
96 if ( !sEntName
.getLength() )
97 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ),
98 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ),
101 ::rtl::OUString aEmbedFactory
= m_aConfigHelper
.GetFactoryNameByClassID( aClassID
);
102 if ( !aEmbedFactory
.getLength() )
104 // use system fallback
105 // TODO: in future users factories can be tested
106 aEmbedFactory
= ::rtl::OUString::createFromAscii( "com.sun.star.embed.OLEEmbeddedObjectFactory" );
109 uno::Reference
< uno::XInterface
> xFact( m_xFactory
->createInstance( aEmbedFactory
) );
110 uno::Reference
< embed::XEmbedObjectCreator
> xEmbCreator( xFact
, uno::UNO_QUERY
);
111 if ( xEmbCreator
.is() )
112 return xEmbCreator
->createInstanceInitNew( aClassID
, aClassName
, xStorage
, sEntName
, lObjArgs
);
114 uno::Reference
< embed::XEmbedObjectFactory
> xEmbFact( xFact
, uno::UNO_QUERY
);
115 if ( !xEmbFact
.is() )
116 throw uno::RuntimeException();
117 return xEmbFact
->createInstanceUserInit( aClassID
, aClassName
, xStorage
, sEntName
, embed::EntryInitModes::TRUNCATE_INIT
, uno::Sequence
< beans::PropertyValue
>(), lObjArgs
);
120 //-------------------------------------------------------------------------
121 uno::Reference
< uno::XInterface
> SAL_CALL
UNOEmbeddedObjectCreator::createInstanceInitFromEntry(
122 const uno::Reference
< embed::XStorage
>& xStorage
,
123 const ::rtl::OUString
& sEntName
,
124 const uno::Sequence
< beans::PropertyValue
>& aMedDescr
,
125 const uno::Sequence
< beans::PropertyValue
>& lObjArgs
)
126 throw ( lang::IllegalArgumentException
,
127 container::NoSuchElementException
,
130 uno::RuntimeException
)
132 RTL_LOGFILE_CONTEXT( aLog
, "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceInitFromEntry" );
134 if ( !xStorage
.is() )
135 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ),
136 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ),
139 if ( !sEntName
.getLength() )
140 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ),
141 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ),
144 uno::Reference
< container::XNameAccess
> xNameAccess( xStorage
, uno::UNO_QUERY
);
145 if ( !xNameAccess
.is() )
146 throw uno::RuntimeException(); //TODO
148 // detect entry existence
149 if ( !xNameAccess
->hasByName( sEntName
) )
150 throw container::NoSuchElementException();
152 ::rtl::OUString aMediaType
;
153 ::rtl::OUString aEmbedFactory
;
154 if ( xStorage
->isStorageElement( sEntName
) )
156 // the object must be based on storage
157 uno::Reference
< embed::XStorage
> xSubStorage
=
158 xStorage
->openStorageElement( sEntName
, embed::ElementModes::READ
);
160 uno::Reference
< beans::XPropertySet
> xPropSet( xSubStorage
, uno::UNO_QUERY
);
161 if ( !xPropSet
.is() )
162 throw uno::RuntimeException();
165 uno::Any aAny
= xPropSet
->getPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ) );
168 catch ( uno::Exception
& )
173 uno::Reference
< lang::XComponent
> xComp( xSubStorage
, uno::UNO_QUERY
);
177 catch ( uno::Exception
& )
183 // the object must be based on stream
184 // it means for now that this is an OLE object
186 // the object will be created as embedded object
187 // after it is loaded it can detect that it is a link
189 uno::Reference
< io::XStream
> xSubStream
=
190 xStorage
->openStreamElement( sEntName
, embed::ElementModes::READ
);
192 uno::Reference
< beans::XPropertySet
> xPropSet( xSubStream
, uno::UNO_QUERY
);
193 if ( !xPropSet
.is() )
194 throw uno::RuntimeException();
197 uno::Any aAny
= xPropSet
->getPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ) );
199 if ( aMediaType
.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/vnd.sun.star.oleobject" ) ) ) )
200 aEmbedFactory
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.OLEEmbeddedObjectFactory" ) );
202 catch ( uno::Exception
& )
207 uno::Reference
< lang::XComponent
> xComp( xSubStream
, uno::UNO_QUERY
);
211 catch ( uno::Exception
& )
216 OSL_ENSURE( aMediaType
.getLength(), "No media type is specified for the object!" );
217 if ( aMediaType
.getLength() && !aEmbedFactory
.getLength() )
218 aEmbedFactory
= m_aConfigHelper
.GetFactoryNameByMediaType( aMediaType
);
220 if ( aEmbedFactory
.getLength() )
222 uno::Reference
< uno::XInterface
> xFact
= m_xFactory
->createInstance( aEmbedFactory
);
224 uno::Reference
< embed::XEmbedObjectCreator
> xEmbCreator( xFact
, uno::UNO_QUERY
);
225 if ( xEmbCreator
.is() )
226 return xEmbCreator
->createInstanceInitFromEntry( xStorage
, sEntName
, aMedDescr
, lObjArgs
);
228 uno::Reference
< embed::XEmbedObjectFactory
> xEmbFact( xFact
, uno::UNO_QUERY
);
230 return xEmbFact
->createInstanceUserInit( uno::Sequence
< sal_Int8
>(), ::rtl::OUString(), xStorage
, sEntName
, embed::EntryInitModes::DEFAULT_INIT
, aMedDescr
, lObjArgs
);
233 // the default object should be created, it will allow to store the contents on the next saving
234 uno::Reference
< uno::XInterface
> xResult( static_cast< cppu::OWeakObject
* >( new ODummyEmbeddedObject() ) );
235 uno::Reference
< embed::XEmbedPersist
> xPersist( xResult
, uno::UNO_QUERY_THROW
);
236 xPersist
->setPersistentEntry( xStorage
, sEntName
, embed::EntryInitModes::DEFAULT_INIT
, aMedDescr
, lObjArgs
);
240 //-------------------------------------------------------------------------
241 uno::Reference
< uno::XInterface
> SAL_CALL
UNOEmbeddedObjectCreator::createInstanceInitFromMediaDescriptor(
242 const uno::Reference
< embed::XStorage
>& xStorage
,
243 const ::rtl::OUString
& sEntName
,
244 const uno::Sequence
< beans::PropertyValue
>& aMediaDescr
,
245 const uno::Sequence
< beans::PropertyValue
>& lObjArgs
)
246 throw ( lang::IllegalArgumentException
,
249 uno::RuntimeException
)
251 RTL_LOGFILE_CONTEXT( aLog
, "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceInitFromMediaDescriptor" );
253 // TODO: use lObjArgs
255 if ( !xStorage
.is() )
256 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ),
257 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ),
260 if ( !sEntName
.getLength() )
261 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ),
262 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ),
265 uno::Reference
< uno::XInterface
> xResult
;
266 uno::Sequence
< beans::PropertyValue
> aTempMedDescr( aMediaDescr
);
268 // check if there is FilterName
269 ::rtl::OUString aFilterName
= m_aConfigHelper
.UpdateMediaDescriptorWithFilterName( aTempMedDescr
, sal_False
);
271 if ( aFilterName
.getLength() )
273 // the object can be loaded by one of the office application
274 uno::Reference
< embed::XEmbedObjectCreator
> xOOoEmbCreator(
275 m_xFactory
->createInstance(
276 ::rtl::OUString::createFromAscii( "com.sun.star.embed.OOoEmbeddedObjectFactory" ) ),
278 if ( !xOOoEmbCreator
.is() )
279 throw uno::RuntimeException(); // TODO:
281 xResult
= xOOoEmbCreator
->createInstanceInitFromMediaDescriptor( xStorage
,
288 // must be an OLE object
290 // TODO: in future, when more object types are possible this place seems
291 // to be a weak one, probably configuration must provide a type detection service
292 // for every factory, so any file could go through services until it is recognized
293 // or there is no more services
294 // Or for example the typename can be used to detect object type if typedetection
295 // was also extended.
297 uno::Reference
< embed::XEmbedObjectCreator
> xOleEmbCreator(
298 m_xFactory
->createInstance(
299 ::rtl::OUString::createFromAscii( "com.sun.star.embed.OLEEmbeddedObjectFactory" ) ),
301 if ( !xOleEmbCreator
.is() )
302 throw uno::RuntimeException(); // TODO:
304 xResult
= xOleEmbCreator
->createInstanceInitFromMediaDescriptor( xStorage
, sEntName
, aTempMedDescr
, lObjArgs
);
310 //-------------------------------------------------------------------------
311 uno::Reference
< uno::XInterface
> SAL_CALL
UNOEmbeddedObjectCreator::createInstanceUserInit(
312 const uno::Sequence
< sal_Int8
>& aClassID
,
313 const ::rtl::OUString
& sClassName
,
314 const uno::Reference
< embed::XStorage
>& xStorage
,
315 const ::rtl::OUString
& sEntName
,
316 sal_Int32 nEntryConnectionMode
,
317 const uno::Sequence
< beans::PropertyValue
>& aArgs
,
318 const uno::Sequence
< beans::PropertyValue
>& aObjectArgs
)
319 throw ( lang::IllegalArgumentException
,
322 uno::RuntimeException
)
324 RTL_LOGFILE_CONTEXT( aLog
, "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceUserInit" );
326 uno::Reference
< uno::XInterface
> xResult
;
328 if ( !xStorage
.is() )
329 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ),
330 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ),
333 if ( !sEntName
.getLength() )
334 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ),
335 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ),
338 ::rtl::OUString aEmbedFactory
= m_aConfigHelper
.GetFactoryNameByClassID( aClassID
);
339 uno::Reference
< embed::XEmbedObjectFactory
> xEmbFactory(
340 m_xFactory
->createInstance( aEmbedFactory
),
342 if ( !xEmbFactory
.is() )
343 throw uno::RuntimeException(); // TODO:
345 return xEmbFactory
->createInstanceUserInit( aClassID
,
349 nEntryConnectionMode
,
354 //-------------------------------------------------------------------------
355 uno::Reference
< uno::XInterface
> SAL_CALL
UNOEmbeddedObjectCreator::createInstanceLink(
356 const uno::Reference
< embed::XStorage
>& xStorage
,
357 const ::rtl::OUString
& sEntName
,
358 const uno::Sequence
< beans::PropertyValue
>& aMediaDescr
,
359 const uno::Sequence
< beans::PropertyValue
>& lObjArgs
)
360 throw ( lang::IllegalArgumentException
,
363 uno::RuntimeException
)
365 RTL_LOGFILE_CONTEXT( aLog
, "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceLink" );
367 uno::Reference
< uno::XInterface
> xResult
;
369 uno::Sequence
< beans::PropertyValue
> aTempMedDescr( aMediaDescr
);
371 // check if there is URL, URL must exist
372 ::rtl::OUString aURL
;
373 for ( sal_Int32 nInd
= 0; nInd
< aTempMedDescr
.getLength(); nInd
++ )
374 if ( aTempMedDescr
[nInd
].Name
.equalsAscii( "URL" ) )
375 aTempMedDescr
[nInd
].Value
>>= aURL
;
377 if ( !aURL
.getLength() )
378 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No URL for the link is provided!\n" ),
379 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ),
382 ::rtl::OUString aFilterName
= m_aConfigHelper
.UpdateMediaDescriptorWithFilterName( aTempMedDescr
, sal_False
);
384 if ( aFilterName
.getLength() )
386 // the object can be loaded by one of the office application
387 uno::Reference
< embed::XLinkCreator
> xOOoLinkCreator(
388 m_xFactory
->createInstance(
389 ::rtl::OUString::createFromAscii( "com.sun.star.embed.OOoEmbeddedObjectFactory" ) ),
391 if ( !xOOoLinkCreator
.is() )
392 throw uno::RuntimeException(); // TODO:
394 xResult
= xOOoLinkCreator
->createInstanceLink( xStorage
,
401 // must be an OLE link
403 // TODO: in future, when more object types are possible this place seems
404 // to be a weak one, probably configuration must provide a type detection service
405 // for every factory, so any file could go through services until it is recognized
406 // or there is no more services
407 // Or for example the typename can be used to detect object type if typedetection
408 // was also extended.
410 if ( !xStorage
.is() )
411 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ),
412 uno::Reference
< uno::XInterface
>(
413 static_cast< ::cppu::OWeakObject
* >(this) ),
416 if ( !sEntName
.getLength() )
417 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ),
418 uno::Reference
< uno::XInterface
>(
419 static_cast< ::cppu::OWeakObject
* >(this) ),
422 uno::Reference
< embed::XLinkCreator
> xLinkCreator(
423 m_xFactory
->createInstance(
424 ::rtl::OUString::createFromAscii( "com.sun.star.embed.OLEEmbeddedObjectFactory" ) ),
426 if ( !xLinkCreator
.is() )
427 throw uno::RuntimeException(); // TODO:
429 xResult
= xLinkCreator
->createInstanceLink( xStorage
, sEntName
, aTempMedDescr
, lObjArgs
);
435 //-------------------------------------------------------------------------
436 uno::Reference
< uno::XInterface
> SAL_CALL
UNOEmbeddedObjectCreator::createInstanceLinkUserInit(
437 const uno::Sequence
< sal_Int8
>& aClassID
,
438 const ::rtl::OUString
& aClassName
,
439 const uno::Reference
< embed::XStorage
>& xStorage
,
440 const ::rtl::OUString
& sEntName
,
441 const uno::Sequence
< beans::PropertyValue
>& lArguments
,
442 const uno::Sequence
< beans::PropertyValue
>& lObjArgs
)
443 throw ( lang::IllegalArgumentException
,
446 uno::RuntimeException
)
448 RTL_LOGFILE_CONTEXT( aLog
, "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceLinkUserInit" );
450 uno::Reference
< uno::XInterface
> xResult
;
452 ::rtl::OUString aEmbedFactory
= m_aConfigHelper
.GetFactoryNameByClassID( aClassID
);
453 uno::Reference
< embed::XLinkFactory
> xLinkFactory(
454 m_xFactory
->createInstance( aEmbedFactory
),
456 if ( !xLinkFactory
.is() )
457 throw uno::RuntimeException(); // TODO:
459 return xLinkFactory
->createInstanceLinkUserInit( aClassID
,
468 //-------------------------------------------------------------------------
469 ::rtl::OUString SAL_CALL
UNOEmbeddedObjectCreator::getImplementationName()
470 throw ( uno::RuntimeException
)
472 return impl_staticGetImplementationName();
475 //-------------------------------------------------------------------------
476 sal_Bool SAL_CALL
UNOEmbeddedObjectCreator::supportsService( const ::rtl::OUString
& ServiceName
)
477 throw ( uno::RuntimeException
)
479 uno::Sequence
< ::rtl::OUString
> aSeq
= impl_staticGetSupportedServiceNames();
481 for ( sal_Int32 nInd
= 0; nInd
< aSeq
.getLength(); nInd
++ )
482 if ( ServiceName
.compareTo( aSeq
[nInd
] ) == 0 )
488 //-------------------------------------------------------------------------
489 uno::Sequence
< ::rtl::OUString
> SAL_CALL
UNOEmbeddedObjectCreator::getSupportedServiceNames()
490 throw ( uno::RuntimeException
)
492 return impl_staticGetSupportedServiceNames();