Version 4.2.0.1, tag libreoffice-4.2.0.1
[LibreOffice.git] / embeddedobj / source / general / xcreator.cxx
blobf909ba5ff2bf3fe8df8e6c62d6ceea0fc500aabb
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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";
48 return aRet;
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,
72 io::IOException,
73 uno::Exception,
74 uno::RuntimeException)
76 SAL_INFO( "embeddedobj.general", "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceInitNew" );
78 uno::Reference< uno::XInterface > xResult;
80 if ( !xStorage.is() )
81 throw lang::IllegalArgumentException( OUString( "No parent storage is provided!\n" ),
82 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
83 3 );
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) ),
88 4 );
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,
117 io::IOException,
118 uno::Exception,
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) ),
126 1 );
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) ),
131 2 );
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();
141 OUString aMediaType;
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();
153 try {
154 uno::Any aAny = xPropSet->getPropertyValue("MediaType");
155 aAny >>= aMediaType;
157 catch ( const uno::Exception& )
161 try {
162 uno::Reference< lang::XComponent > xComp( xSubStorage, uno::UNO_QUERY );
163 if ( xComp.is() )
164 xComp->dispose();
166 catch ( const uno::Exception& )
170 else
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();
185 try {
186 uno::Any aAny = xPropSet->getPropertyValue("MediaType");
187 aAny >>= aMediaType;
188 if ( aMediaType == "application/vnd.sun.star.oleobject" )
189 aEmbedFactory = "com.sun.star.embed.OLEEmbeddedObjectFactory";
191 catch ( const uno::Exception& )
195 try {
196 uno::Reference< lang::XComponent > xComp( xSubStream, uno::UNO_QUERY );
197 if ( xComp.is() )
198 xComp->dispose();
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 );
218 if ( xEmbFact.is() )
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 );
226 return xResult;
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,
236 io::IOException,
237 uno::Exception,
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) ),
247 1 );
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) ),
252 2 );
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,
267 sEntName,
268 aTempMedDescr,
269 lObjArgs );
271 else
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 );
288 return xResult;
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,
301 io::IOException,
302 uno::Exception,
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) ),
312 3 );
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) ),
317 4 );
319 OUString aEmbedFactory = m_aConfigHelper.GetFactoryNameByClassID( aClassID );
320 uno::Reference< embed::XEmbedObjectFactory > xEmbFactory(
321 m_xContext->getServiceManager()->createInstanceWithContext(aEmbedFactory, m_xContext),
322 uno::UNO_QUERY );
323 if ( !xEmbFactory.is() )
324 throw uno::RuntimeException(); // TODO:
326 return xEmbFactory->createInstanceUserInit( aClassID,
327 sClassName,
328 xStorage,
329 sEntName,
330 nEntryConnectionMode,
331 aArgs,
332 aObjectArgs );
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,
342 io::IOException,
343 uno::Exception,
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
353 OUString aURL;
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) ),
361 3 );
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,
372 sEntName,
373 aTempMedDescr,
374 lObjArgs );
376 else
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) ),
391 3 );
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) ),
397 4 );
399 uno::Reference< embed::XEmbeddedObjectCreator > xLinkCreator =
400 embed::OLEEmbeddedObjectFactory::create( m_xContext);
402 xResult = xLinkCreator->createInstanceLink( xStorage, sEntName, aTempMedDescr, lObjArgs );
405 return xResult;
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,
417 io::IOException,
418 uno::Exception,
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),
428 uno::UNO_QUERY );
429 if ( !xLinkFactory.is() )
430 throw uno::RuntimeException(); // TODO:
432 return xLinkFactory->createInstanceLinkUserInit( aClassID,
433 aClassName,
434 xStorage,
435 sEntName,
436 lArguments,
437 lObjArgs );
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: */