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"));
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
,
81 uno::RuntimeException
)
83 RTL_LOGFILE_CONTEXT( aLog
, "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceInitNew" );
85 uno::Reference
< uno::XInterface
> xResult
;
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) ),
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) ),
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
,
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) ),
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) ),
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();
161 uno::Any aAny
= xPropSet
->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ));
164 catch ( const uno::Exception
& )
169 uno::Reference
< lang::XComponent
> xComp( xSubStorage
, uno::UNO_QUERY
);
173 catch ( const uno::Exception
& )
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();
193 uno::Any aAny
= xPropSet
->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ));
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
& )
203 uno::Reference
< lang::XComponent
> xComp( xSubStream
, uno::UNO_QUERY
);
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
);
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
);
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
,
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) ),
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) ),
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" ) )),
274 if ( !xOOoEmbCreator
.is() )
275 throw uno::RuntimeException(); // TODO:
277 xResult
= xOOoEmbCreator
->createInstanceInitFromMediaDescriptor( xStorage
,
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" ) )),
297 if ( !xOleEmbCreator
.is() )
298 throw uno::RuntimeException(); // TODO:
300 xResult
= xOleEmbCreator
->createInstanceInitFromMediaDescriptor( xStorage
, sEntName
, aTempMedDescr
, lObjArgs
);
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
,
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) ),
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) ),
334 ::rtl::OUString aEmbedFactory
= m_aConfigHelper
.GetFactoryNameByClassID( aClassID
);
335 uno::Reference
< embed::XEmbedObjectFactory
> xEmbFactory(
336 m_xFactory
->createInstance( aEmbedFactory
),
338 if ( !xEmbFactory
.is() )
339 throw uno::RuntimeException(); // TODO:
341 return xEmbFactory
->createInstanceUserInit( aClassID
,
345 nEntryConnectionMode
,
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
,
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) ),
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" ) )),
387 if ( !xOOoLinkCreator
.is() )
388 throw uno::RuntimeException(); // TODO:
390 xResult
= xOOoLinkCreator
->createInstanceLink( xStorage
,
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) ),
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) ),
418 uno::Reference
< embed::XLinkCreator
> xLinkCreator(
419 m_xFactory
->createInstance(
420 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.OLEEmbeddedObjectFactory" ) )),
422 if ( !xLinkCreator
.is() )
423 throw uno::RuntimeException(); // TODO:
425 xResult
= xLinkCreator
->createInstanceLink( xStorage
, sEntName
, aTempMedDescr
, lObjArgs
);
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
,
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
),
452 if ( !xLinkFactory
.is() )
453 throw uno::RuntimeException(); // TODO:
455 return xLinkFactory
->createInstanceLinkUserInit( aClassID
,
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 )
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: */