1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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>
32 #include <comphelper/processfactory.hxx>
33 #include <cppuhelper/supportsservice.hxx>
35 #include <xcreator.hxx>
36 #include <dummyobject.hxx>
39 using namespace ::com::sun::star
;
42 //-------------------------------------------------------------------------
43 uno::Sequence
< OUString
> SAL_CALL
UNOEmbeddedObjectCreator::impl_staticGetSupportedServiceNames()
45 uno::Sequence
< OUString
> aRet(2);
46 aRet
[0] = "com.sun.star.embed.EmbeddedObjectCreator";
47 aRet
[1] = "com.sun.star.comp.embed.EmbeddedObjectCreator";
51 //-------------------------------------------------------------------------
52 OUString SAL_CALL
UNOEmbeddedObjectCreator::impl_staticGetImplementationName()
54 return OUString("com.sun.star.comp.embed.EmbeddedObjectCreator");
57 //-------------------------------------------------------------------------
58 uno::Reference
< uno::XInterface
> SAL_CALL
UNOEmbeddedObjectCreator::impl_staticCreateSelfInstance(
59 const uno::Reference
< lang::XMultiServiceFactory
>& xServiceManager
)
61 return uno::Reference
< uno::XInterface
>( *new UNOEmbeddedObjectCreator( comphelper::getComponentContext(xServiceManager
) ) );
64 //-------------------------------------------------------------------------
65 uno::Reference
< uno::XInterface
> SAL_CALL
UNOEmbeddedObjectCreator::createInstanceInitNew(
66 const uno::Sequence
< sal_Int8
>& aClassID
,
67 const OUString
& aClassName
,
68 const uno::Reference
< embed::XStorage
>& xStorage
,
69 const OUString
& sEntName
,
70 const uno::Sequence
< beans::PropertyValue
>& lObjArgs
)
71 throw ( lang::IllegalArgumentException
,
74 uno::RuntimeException
)
76 SAL_INFO( "embeddedobj.general", "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceInitNew" );
78 uno::Reference
< uno::XInterface
> xResult
;
81 throw lang::IllegalArgumentException( OUString( "No parent storage is provided!\n" ),
82 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ),
85 if ( sEntName
.isEmpty() )
86 throw lang::IllegalArgumentException( OUString( "Empty element name is provided!\n" ),
87 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ),
90 OUString aEmbedFactory
= m_aConfigHelper
.GetFactoryNameByClassID( aClassID
);
91 if ( aEmbedFactory
.isEmpty() )
93 // use system fallback
94 // TODO: in future users factories can be tested
95 aEmbedFactory
= "com.sun.star.embed.OLEEmbeddedObjectFactory";
98 uno::Reference
< uno::XInterface
> xFact( m_xContext
->getServiceManager()->createInstanceWithContext(aEmbedFactory
, m_xContext
) );
99 uno::Reference
< embed::XEmbedObjectCreator
> xEmbCreator( xFact
, uno::UNO_QUERY
);
100 if ( xEmbCreator
.is() )
101 return xEmbCreator
->createInstanceInitNew( aClassID
, aClassName
, xStorage
, sEntName
, lObjArgs
);
103 uno::Reference
< embed::XEmbedObjectFactory
> xEmbFact( xFact
, uno::UNO_QUERY
);
104 if ( !xEmbFact
.is() )
105 throw uno::RuntimeException();
106 return xEmbFact
->createInstanceUserInit( aClassID
, aClassName
, xStorage
, sEntName
, embed::EntryInitModes::TRUNCATE_INIT
, uno::Sequence
< beans::PropertyValue
>(), lObjArgs
);
109 //-------------------------------------------------------------------------
110 uno::Reference
< uno::XInterface
> SAL_CALL
UNOEmbeddedObjectCreator::createInstanceInitFromEntry(
111 const uno::Reference
< embed::XStorage
>& xStorage
,
112 const OUString
& sEntName
,
113 const uno::Sequence
< beans::PropertyValue
>& aMedDescr
,
114 const uno::Sequence
< beans::PropertyValue
>& lObjArgs
)
115 throw ( lang::IllegalArgumentException
,
116 container::NoSuchElementException
,
119 uno::RuntimeException
)
121 SAL_INFO( "embeddedobj.general", "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceInitFromEntry" );
123 if ( !xStorage
.is() )
124 throw lang::IllegalArgumentException( OUString( "No parent storage is provided!\n" ),
125 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ),
128 if ( sEntName
.isEmpty() )
129 throw lang::IllegalArgumentException( OUString( "Empty element name is provided!\n" ),
130 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ),
133 uno::Reference
< container::XNameAccess
> xNameAccess( xStorage
, uno::UNO_QUERY
);
134 if ( !xNameAccess
.is() )
135 throw uno::RuntimeException(); //TODO
137 // detect entry existence
138 if ( !xNameAccess
->hasByName( sEntName
) )
139 throw container::NoSuchElementException();
142 OUString aEmbedFactory
;
143 if ( xStorage
->isStorageElement( sEntName
) )
145 // the object must be based on storage
146 uno::Reference
< embed::XStorage
> xSubStorage
=
147 xStorage
->openStorageElement( sEntName
, embed::ElementModes::READ
);
149 uno::Reference
< beans::XPropertySet
> xPropSet( xSubStorage
, uno::UNO_QUERY
);
150 if ( !xPropSet
.is() )
151 throw uno::RuntimeException();
154 uno::Any aAny
= xPropSet
->getPropertyValue("MediaType");
157 catch ( const uno::Exception
& )
162 uno::Reference
< lang::XComponent
> xComp( xSubStorage
, uno::UNO_QUERY
);
166 catch ( const uno::Exception
& )
172 // the object must be based on stream
173 // it means for now that this is an OLE object
175 // the object will be created as embedded object
176 // after it is loaded it can detect that it is a link
178 uno::Reference
< io::XStream
> xSubStream
=
179 xStorage
->openStreamElement( sEntName
, embed::ElementModes::READ
);
181 uno::Reference
< beans::XPropertySet
> xPropSet( xSubStream
, uno::UNO_QUERY
);
182 if ( !xPropSet
.is() )
183 throw uno::RuntimeException();
186 uno::Any aAny
= xPropSet
->getPropertyValue("MediaType");
188 if ( aMediaType
== "application/vnd.sun.star.oleobject" )
189 aEmbedFactory
= "com.sun.star.embed.OLEEmbeddedObjectFactory";
191 catch ( const uno::Exception
& )
196 uno::Reference
< lang::XComponent
> xComp( xSubStream
, uno::UNO_QUERY
);
200 catch ( const uno::Exception
& )
205 OSL_ENSURE( !aMediaType
.isEmpty(), "No media type is specified for the object!" );
206 if ( !aMediaType
.isEmpty() && aEmbedFactory
.isEmpty() )
207 aEmbedFactory
= m_aConfigHelper
.GetFactoryNameByMediaType( aMediaType
);
209 if ( !aEmbedFactory
.isEmpty() )
211 uno::Reference
< uno::XInterface
> xFact
= m_xContext
->getServiceManager()->createInstanceWithContext(aEmbedFactory
, m_xContext
);
213 uno::Reference
< embed::XEmbedObjectCreator
> xEmbCreator( xFact
, uno::UNO_QUERY
);
214 if ( xEmbCreator
.is() )
215 return xEmbCreator
->createInstanceInitFromEntry( xStorage
, sEntName
, aMedDescr
, lObjArgs
);
217 uno::Reference
< embed::XEmbedObjectFactory
> xEmbFact( xFact
, uno::UNO_QUERY
);
219 return xEmbFact
->createInstanceUserInit( uno::Sequence
< sal_Int8
>(), OUString(), xStorage
, sEntName
, embed::EntryInitModes::DEFAULT_INIT
, aMedDescr
, lObjArgs
);
222 // the default object should be created, it will allow to store the contents on the next saving
223 uno::Reference
< uno::XInterface
> xResult( static_cast< cppu::OWeakObject
* >( new ODummyEmbeddedObject() ) );
224 uno::Reference
< embed::XEmbedPersist
> xPersist( xResult
, uno::UNO_QUERY_THROW
);
225 xPersist
->setPersistentEntry( xStorage
, sEntName
, embed::EntryInitModes::DEFAULT_INIT
, aMedDescr
, lObjArgs
);
229 //-------------------------------------------------------------------------
230 uno::Reference
< uno::XInterface
> SAL_CALL
UNOEmbeddedObjectCreator::createInstanceInitFromMediaDescriptor(
231 const uno::Reference
< embed::XStorage
>& xStorage
,
232 const OUString
& sEntName
,
233 const uno::Sequence
< beans::PropertyValue
>& aMediaDescr
,
234 const uno::Sequence
< beans::PropertyValue
>& lObjArgs
)
235 throw ( lang::IllegalArgumentException
,
238 uno::RuntimeException
)
240 SAL_INFO( "embeddedobj.general", "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceInitFromMediaDescriptor" );
242 // TODO: use lObjArgs
244 if ( !xStorage
.is() )
245 throw lang::IllegalArgumentException( OUString( "No parent storage is provided!\n" ),
246 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ),
249 if ( sEntName
.isEmpty() )
250 throw lang::IllegalArgumentException( OUString( "Empty element name is provided!\n" ),
251 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ),
254 uno::Reference
< uno::XInterface
> xResult
;
255 uno::Sequence
< beans::PropertyValue
> aTempMedDescr( aMediaDescr
);
257 // check if there is FilterName
258 OUString aFilterName
= m_aConfigHelper
.UpdateMediaDescriptorWithFilterName( aTempMedDescr
, sal_False
);
260 if ( !aFilterName
.isEmpty() )
262 // the object can be loaded by one of the office application
263 uno::Reference
< embed::XEmbeddedObjectCreator
> xOOoEmbCreator
=
264 embed::OOoEmbeddedObjectFactory::create( m_xContext
);
266 xResult
= xOOoEmbCreator
->createInstanceInitFromMediaDescriptor( xStorage
,
273 // must be an OLE object
275 // TODO: in future, when more object types are possible this place seems
276 // to be a weak one, probably configuration must provide a type detection service
277 // for every factory, so any file could go through services until it is recognized
278 // or there is no more services
279 // Or for example the typename can be used to detect object type if typedetection
280 // was also extended.
282 uno::Reference
< embed::XEmbeddedObjectCreator
> xOleEmbCreator
=
283 embed::OLEEmbeddedObjectFactory::create( m_xContext
);
285 xResult
= xOleEmbCreator
->createInstanceInitFromMediaDescriptor( xStorage
, sEntName
, aTempMedDescr
, lObjArgs
);
291 //-------------------------------------------------------------------------
292 uno::Reference
< uno::XInterface
> SAL_CALL
UNOEmbeddedObjectCreator::createInstanceUserInit(
293 const uno::Sequence
< sal_Int8
>& aClassID
,
294 const OUString
& sClassName
,
295 const uno::Reference
< embed::XStorage
>& xStorage
,
296 const OUString
& sEntName
,
297 sal_Int32 nEntryConnectionMode
,
298 const uno::Sequence
< beans::PropertyValue
>& aArgs
,
299 const uno::Sequence
< beans::PropertyValue
>& aObjectArgs
)
300 throw ( lang::IllegalArgumentException
,
303 uno::RuntimeException
)
305 SAL_INFO( "embeddedobj.general", "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceUserInit" );
307 uno::Reference
< uno::XInterface
> xResult
;
309 if ( !xStorage
.is() )
310 throw lang::IllegalArgumentException( OUString( "No parent storage is provided!\n" ),
311 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ),
314 if ( sEntName
.isEmpty() )
315 throw lang::IllegalArgumentException( OUString( "Empty element name is provided!\n" ),
316 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ),
319 OUString aEmbedFactory
= m_aConfigHelper
.GetFactoryNameByClassID( aClassID
);
320 uno::Reference
< embed::XEmbedObjectFactory
> xEmbFactory(
321 m_xContext
->getServiceManager()->createInstanceWithContext(aEmbedFactory
, m_xContext
),
323 if ( !xEmbFactory
.is() )
324 throw uno::RuntimeException(); // TODO:
326 return xEmbFactory
->createInstanceUserInit( aClassID
,
330 nEntryConnectionMode
,
335 //-------------------------------------------------------------------------
336 uno::Reference
< uno::XInterface
> SAL_CALL
UNOEmbeddedObjectCreator::createInstanceLink(
337 const uno::Reference
< embed::XStorage
>& xStorage
,
338 const OUString
& sEntName
,
339 const uno::Sequence
< beans::PropertyValue
>& aMediaDescr
,
340 const uno::Sequence
< beans::PropertyValue
>& lObjArgs
)
341 throw ( lang::IllegalArgumentException
,
344 uno::RuntimeException
)
346 SAL_INFO( "embeddedobj.general", "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceLink" );
348 uno::Reference
< uno::XInterface
> xResult
;
350 uno::Sequence
< beans::PropertyValue
> aTempMedDescr( aMediaDescr
);
352 // check if there is URL, URL must exist
354 for ( sal_Int32 nInd
= 0; nInd
< aTempMedDescr
.getLength(); nInd
++ )
355 if ( aTempMedDescr
[nInd
].Name
== "URL" )
356 aTempMedDescr
[nInd
].Value
>>= aURL
;
358 if ( aURL
.isEmpty() )
359 throw lang::IllegalArgumentException( OUString( "No URL for the link is provided!\n" ),
360 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ),
363 OUString aFilterName
= m_aConfigHelper
.UpdateMediaDescriptorWithFilterName( aTempMedDescr
, sal_False
);
365 if ( !aFilterName
.isEmpty() )
367 // the object can be loaded by one of the office application
368 uno::Reference
< embed::XEmbeddedObjectCreator
> xOOoLinkCreator
=
369 embed::OOoEmbeddedObjectFactory::create( m_xContext
);
371 xResult
= xOOoLinkCreator
->createInstanceLink( xStorage
,
378 // must be an OLE link
380 // TODO: in future, when more object types are possible this place seems
381 // to be a weak one, probably configuration must provide a type detection service
382 // for every factory, so any file could go through services until it is recognized
383 // or there is no more services
384 // Or for example the typename can be used to detect object type if typedetection
385 // was also extended.
387 if ( !xStorage
.is() )
388 throw lang::IllegalArgumentException( OUString( "No parent storage is provided!\n" ),
389 uno::Reference
< uno::XInterface
>(
390 static_cast< ::cppu::OWeakObject
* >(this) ),
393 if ( sEntName
.isEmpty() )
394 throw lang::IllegalArgumentException( OUString( "Empty element name is provided!\n" ),
395 uno::Reference
< uno::XInterface
>(
396 static_cast< ::cppu::OWeakObject
* >(this) ),
399 uno::Reference
< embed::XEmbeddedObjectCreator
> xLinkCreator
=
400 embed::OLEEmbeddedObjectFactory::create( m_xContext
);
402 xResult
= xLinkCreator
->createInstanceLink( xStorage
, sEntName
, aTempMedDescr
, lObjArgs
);
408 //-------------------------------------------------------------------------
409 uno::Reference
< uno::XInterface
> SAL_CALL
UNOEmbeddedObjectCreator::createInstanceLinkUserInit(
410 const uno::Sequence
< sal_Int8
>& aClassID
,
411 const OUString
& aClassName
,
412 const uno::Reference
< embed::XStorage
>& xStorage
,
413 const OUString
& sEntName
,
414 const uno::Sequence
< beans::PropertyValue
>& lArguments
,
415 const uno::Sequence
< beans::PropertyValue
>& lObjArgs
)
416 throw ( lang::IllegalArgumentException
,
419 uno::RuntimeException
)
421 SAL_INFO( "embeddedobj.general", "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceLinkUserInit" );
423 uno::Reference
< uno::XInterface
> xResult
;
425 OUString aEmbedFactory
= m_aConfigHelper
.GetFactoryNameByClassID( aClassID
);
426 uno::Reference
< embed::XLinkFactory
> xLinkFactory(
427 m_xContext
->getServiceManager()->createInstanceWithContext(aEmbedFactory
, m_xContext
),
429 if ( !xLinkFactory
.is() )
430 throw uno::RuntimeException(); // TODO:
432 return xLinkFactory
->createInstanceLinkUserInit( aClassID
,
441 //-------------------------------------------------------------------------
442 OUString SAL_CALL
UNOEmbeddedObjectCreator::getImplementationName()
443 throw ( uno::RuntimeException
)
445 return impl_staticGetImplementationName();
448 sal_Bool SAL_CALL
UNOEmbeddedObjectCreator::supportsService( const OUString
& ServiceName
)
449 throw ( uno::RuntimeException
)
451 return cppu::supportsService(this, ServiceName
);
454 //-------------------------------------------------------------------------
455 uno::Sequence
< OUString
> SAL_CALL
UNOEmbeddedObjectCreator::getSupportedServiceNames()
456 throw ( uno::RuntimeException
)
458 return impl_staticGetSupportedServiceNames();
461 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */