fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / embeddedobj / source / general / xcreator.cxx
blob8ccff0c81074135bb71b4976fe6e2399fdf649be
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>
34 #include <comphelper/documentconstants.hxx>
36 #include <xcreator.hxx>
37 #include <dummyobject.hxx>
40 using namespace ::com::sun::star;
44 uno::Sequence< OUString > SAL_CALL UNOEmbeddedObjectCreator::impl_staticGetSupportedServiceNames()
46 uno::Sequence< OUString > aRet(2);
47 aRet[0] = "com.sun.star.embed.EmbeddedObjectCreator";
48 aRet[1] = "com.sun.star.comp.embed.EmbeddedObjectCreator";
49 return aRet;
53 OUString SAL_CALL UNOEmbeddedObjectCreator::impl_staticGetImplementationName()
55 return OUString("com.sun.star.comp.embed.EmbeddedObjectCreator");
59 uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::impl_staticCreateSelfInstance(
60 const uno::Reference< lang::XMultiServiceFactory >& xServiceManager )
62 return uno::Reference< uno::XInterface >( *new UNOEmbeddedObjectCreator( comphelper::getComponentContext(xServiceManager) ) );
66 uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInstanceInitNew(
67 const uno::Sequence< sal_Int8 >& aClassID,
68 const OUString& aClassName,
69 const uno::Reference< embed::XStorage >& xStorage,
70 const OUString& sEntName,
71 const uno::Sequence< beans::PropertyValue >& lObjArgs )
72 throw ( lang::IllegalArgumentException,
73 io::IOException,
74 uno::Exception,
75 uno::RuntimeException, std::exception)
77 uno::Reference< uno::XInterface > xResult;
79 if ( !xStorage.is() )
80 throw lang::IllegalArgumentException( "No parent storage is provided!",
81 static_cast< ::cppu::OWeakObject* >(this),
82 3 );
84 if ( sEntName.isEmpty() )
85 throw lang::IllegalArgumentException( "Empty element name is provided!",
86 static_cast< ::cppu::OWeakObject* >(this),
87 4 );
89 OUString aEmbedFactory = m_aConfigHelper.GetFactoryNameByClassID( aClassID );
90 if ( aEmbedFactory.isEmpty() )
92 // use system fallback
93 // TODO: in future users factories can be tested
94 aEmbedFactory = "com.sun.star.embed.OLEEmbeddedObjectFactory";
97 uno::Reference < uno::XInterface > xFact( m_xContext->getServiceManager()->createInstanceWithContext(aEmbedFactory, m_xContext) );
98 uno::Reference< embed::XEmbedObjectCreator > xEmbCreator( xFact, uno::UNO_QUERY );
99 if ( xEmbCreator.is() )
100 return xEmbCreator->createInstanceInitNew( aClassID, aClassName, xStorage, sEntName, lObjArgs );
102 uno::Reference < embed::XEmbedObjectFactory > xEmbFact( xFact, uno::UNO_QUERY );
103 if ( !xEmbFact.is() )
104 throw uno::RuntimeException();
105 return xEmbFact->createInstanceUserInit( aClassID, aClassName, xStorage, sEntName, embed::EntryInitModes::TRUNCATE_INIT, uno::Sequence < beans::PropertyValue >(), lObjArgs);
109 uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInstanceInitFromEntry(
110 const uno::Reference< embed::XStorage >& xStorage,
111 const OUString& sEntName,
112 const uno::Sequence< beans::PropertyValue >& aMedDescr,
113 const uno::Sequence< beans::PropertyValue >& lObjArgs )
114 throw ( lang::IllegalArgumentException,
115 container::NoSuchElementException,
116 io::IOException,
117 uno::Exception,
118 uno::RuntimeException, std::exception)
120 if ( !xStorage.is() )
121 throw lang::IllegalArgumentException( "No parent storage is provided!",
122 static_cast< ::cppu::OWeakObject* >(this),
123 1 );
125 if ( sEntName.isEmpty() )
126 throw lang::IllegalArgumentException( "Empty element name is provided!",
127 static_cast< ::cppu::OWeakObject* >(this),
128 2 );
130 uno::Reference< container::XNameAccess > xNameAccess( xStorage, uno::UNO_QUERY );
131 if ( !xNameAccess.is() )
132 throw uno::RuntimeException(); //TODO
134 // detect entry existence
135 if ( !xNameAccess->hasByName( sEntName ) )
136 throw container::NoSuchElementException();
138 OUString aMediaType;
139 OUString aEmbedFactory;
140 if ( xStorage->isStorageElement( sEntName ) )
142 // the object must be based on storage
143 uno::Reference< embed::XStorage > xSubStorage =
144 xStorage->openStorageElement( sEntName, embed::ElementModes::READ );
146 uno::Reference< beans::XPropertySet > xPropSet( xSubStorage, uno::UNO_QUERY );
147 if ( !xPropSet.is() )
148 throw uno::RuntimeException();
150 try {
151 uno::Any aAny = xPropSet->getPropertyValue("MediaType");
152 aAny >>= aMediaType;
154 catch ( const uno::Exception& )
158 try {
159 uno::Reference< lang::XComponent > xComp( xSubStorage, uno::UNO_QUERY );
160 if ( xComp.is() )
161 xComp->dispose();
163 catch ( const uno::Exception& )
167 else
169 // the object must be based on stream
170 // it means for now that this is an OLE object
172 // the object will be created as embedded object
173 // after it is loaded it can detect that it is a link
175 uno::Reference< io::XStream > xSubStream =
176 xStorage->openStreamElement( sEntName, embed::ElementModes::READ );
178 uno::Reference< beans::XPropertySet > xPropSet( xSubStream, uno::UNO_QUERY );
179 if ( !xPropSet.is() )
180 throw uno::RuntimeException();
182 try {
183 uno::Any aAny = xPropSet->getPropertyValue("MediaType");
184 aAny >>= aMediaType;
185 if ( aMediaType == "application/vnd.sun.star.oleobject" )
186 aEmbedFactory = "com.sun.star.embed.OLEEmbeddedObjectFactory";
188 catch ( const uno::Exception& )
192 try {
193 uno::Reference< lang::XComponent > xComp( xSubStream, uno::UNO_QUERY );
194 if ( xComp.is() )
195 xComp->dispose();
197 catch ( const uno::Exception& )
202 OSL_ENSURE( !aMediaType.isEmpty(), "No media type is specified for the object!" );
203 if ( !aMediaType.isEmpty() && aEmbedFactory.isEmpty() )
205 aEmbedFactory = m_aConfigHelper.GetFactoryNameByMediaType( aMediaType );
207 // If no factory is found, fall back to the FileFormatVersion=6200 filter, Base only has that.
208 if (aEmbedFactory.isEmpty() && aMediaType == MIMETYPE_OASIS_OPENDOCUMENT_DATABASE_ASCII)
209 aEmbedFactory = m_aConfigHelper.GetFactoryNameByMediaType(MIMETYPE_VND_SUN_XML_BASE_ASCII);
212 if ( !aEmbedFactory.isEmpty() )
214 uno::Reference< uno::XInterface > xFact = m_xContext->getServiceManager()->createInstanceWithContext(aEmbedFactory, m_xContext);
216 uno::Reference< embed::XEmbedObjectCreator > xEmbCreator( xFact, uno::UNO_QUERY );
217 if ( xEmbCreator.is() )
218 return xEmbCreator->createInstanceInitFromEntry( xStorage, sEntName, aMedDescr, lObjArgs );
220 uno::Reference < embed::XEmbedObjectFactory > xEmbFact( xFact, uno::UNO_QUERY );
221 if ( xEmbFact.is() )
222 return xEmbFact->createInstanceUserInit( uno::Sequence< sal_Int8 >(), OUString(), xStorage, sEntName, embed::EntryInitModes::DEFAULT_INIT, aMedDescr, lObjArgs);
225 // the default object should be created, it will allow to store the contents on the next saving
226 uno::Reference< uno::XInterface > xResult( static_cast< cppu::OWeakObject* >( new ODummyEmbeddedObject() ) );
227 uno::Reference< embed::XEmbedPersist > xPersist( xResult, uno::UNO_QUERY_THROW );
228 xPersist->setPersistentEntry( xStorage, sEntName, embed::EntryInitModes::DEFAULT_INIT, aMedDescr, lObjArgs );
229 return xResult;
233 uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInstanceInitFromMediaDescriptor(
234 const uno::Reference< embed::XStorage >& xStorage,
235 const OUString& sEntName,
236 const uno::Sequence< beans::PropertyValue >& aMediaDescr,
237 const uno::Sequence< beans::PropertyValue >& lObjArgs )
238 throw ( lang::IllegalArgumentException,
239 io::IOException,
240 uno::Exception,
241 uno::RuntimeException, std::exception)
243 // TODO: use lObjArgs
245 if ( !xStorage.is() )
246 throw lang::IllegalArgumentException( "No parent storage is provided!",
247 static_cast< ::cppu::OWeakObject* >(this),
248 1 );
250 if ( sEntName.isEmpty() )
251 throw lang::IllegalArgumentException( "Empty element name is provided!",
252 static_cast< ::cppu::OWeakObject* >(this),
253 2 );
255 uno::Reference< uno::XInterface > xResult;
256 uno::Sequence< beans::PropertyValue > aTempMedDescr( aMediaDescr );
258 // check if there is FilterName
259 OUString aFilterName = m_aConfigHelper.UpdateMediaDescriptorWithFilterName( aTempMedDescr, false );
261 if ( !aFilterName.isEmpty() )
263 // the object can be loaded by one of the office application
264 uno::Reference< embed::XEmbeddedObjectCreator > xOOoEmbCreator =
265 embed::OOoEmbeddedObjectFactory::create( m_xContext );
267 xResult = xOOoEmbCreator->createInstanceInitFromMediaDescriptor( xStorage,
268 sEntName,
269 aTempMedDescr,
270 lObjArgs );
272 else
274 // must be an OLE object
276 // TODO: in future, when more object types are possible this place seems
277 // to be a weak one, probably configuration must provide a type detection service
278 // for every factory, so any file could go through services until it is recognized
279 // or there is no more services
280 // Or for example the typename can be used to detect object type if typedetection
281 // was also extended.
283 uno::Reference< embed::XEmbeddedObjectCreator > xOleEmbCreator =
284 embed::OLEEmbeddedObjectFactory::create( m_xContext );
286 xResult = xOleEmbCreator->createInstanceInitFromMediaDescriptor( xStorage, sEntName, aTempMedDescr, lObjArgs );
289 return xResult;
293 uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInstanceUserInit(
294 const uno::Sequence< sal_Int8 >& aClassID,
295 const OUString& sClassName,
296 const uno::Reference< embed::XStorage >& xStorage,
297 const OUString& sEntName,
298 sal_Int32 nEntryConnectionMode,
299 const uno::Sequence< beans::PropertyValue >& aArgs,
300 const uno::Sequence< beans::PropertyValue >& aObjectArgs )
301 throw ( lang::IllegalArgumentException,
302 io::IOException,
303 uno::Exception,
304 uno::RuntimeException, std::exception)
306 uno::Reference< uno::XInterface > xResult;
308 if ( !xStorage.is() )
309 throw lang::IllegalArgumentException( "No parent storage is provided!",
310 static_cast< ::cppu::OWeakObject* >(this),
311 3 );
313 if ( sEntName.isEmpty() )
314 throw lang::IllegalArgumentException( "Empty element name is provided!",
315 static_cast< ::cppu::OWeakObject* >(this),
316 4 );
318 OUString aEmbedFactory = m_aConfigHelper.GetFactoryNameByClassID( aClassID );
319 uno::Reference< embed::XEmbedObjectFactory > xEmbFactory(
320 m_xContext->getServiceManager()->createInstanceWithContext(aEmbedFactory, m_xContext),
321 uno::UNO_QUERY );
322 if ( !xEmbFactory.is() )
323 throw uno::RuntimeException(); // TODO:
325 return xEmbFactory->createInstanceUserInit( aClassID,
326 sClassName,
327 xStorage,
328 sEntName,
329 nEntryConnectionMode,
330 aArgs,
331 aObjectArgs );
335 uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInstanceLink(
336 const uno::Reference< embed::XStorage >& xStorage,
337 const OUString& sEntName,
338 const uno::Sequence< beans::PropertyValue >& aMediaDescr,
339 const uno::Sequence< beans::PropertyValue >& lObjArgs )
340 throw ( lang::IllegalArgumentException,
341 io::IOException,
342 uno::Exception,
343 uno::RuntimeException, std::exception )
345 uno::Reference< uno::XInterface > xResult;
347 uno::Sequence< beans::PropertyValue > aTempMedDescr( aMediaDescr );
349 // check if there is URL, URL must exist
350 OUString aURL;
351 for ( sal_Int32 nInd = 0; nInd < aTempMedDescr.getLength(); nInd++ )
352 if ( aTempMedDescr[nInd].Name == "URL" )
353 aTempMedDescr[nInd].Value >>= aURL;
355 if ( aURL.isEmpty() )
356 throw lang::IllegalArgumentException( "No URL for the link is provided!",
357 static_cast< ::cppu::OWeakObject* >(this),
358 3 );
360 OUString aFilterName = m_aConfigHelper.UpdateMediaDescriptorWithFilterName( aTempMedDescr, false );
362 if ( !aFilterName.isEmpty() )
364 // the object can be loaded by one of the office application
365 uno::Reference< embed::XEmbeddedObjectCreator > xOOoLinkCreator =
366 embed::OOoEmbeddedObjectFactory::create( m_xContext );
368 xResult = xOOoLinkCreator->createInstanceLink( xStorage,
369 sEntName,
370 aTempMedDescr,
371 lObjArgs );
373 else
375 // must be an OLE link
377 // TODO: in future, when more object types are possible this place seems
378 // to be a weak one, probably configuration must provide a type detection service
379 // for every factory, so any file could go through services until it is recognized
380 // or there is no more services
381 // Or for example the typename can be used to detect object type if typedetection
382 // was also extended.
384 if ( !xStorage.is() )
385 throw lang::IllegalArgumentException( "No parent storage is provided!",
386 static_cast< ::cppu::OWeakObject* >(this),
387 3 );
389 if ( sEntName.isEmpty() )
390 throw lang::IllegalArgumentException( "Empty element name is provided!",
391 static_cast< ::cppu::OWeakObject* >(this),
392 4 );
394 uno::Reference< embed::XEmbeddedObjectCreator > xLinkCreator =
395 embed::OLEEmbeddedObjectFactory::create( m_xContext);
397 xResult = xLinkCreator->createInstanceLink( xStorage, sEntName, aTempMedDescr, lObjArgs );
400 return xResult;
403 OUString SAL_CALL UNOEmbeddedObjectCreator::getImplementationName()
404 throw ( uno::RuntimeException, std::exception )
406 return impl_staticGetImplementationName();
409 sal_Bool SAL_CALL UNOEmbeddedObjectCreator::supportsService( const OUString& ServiceName )
410 throw ( uno::RuntimeException, std::exception )
412 return cppu::supportsService(this, ServiceName);
415 uno::Sequence< OUString > SAL_CALL UNOEmbeddedObjectCreator::getSupportedServiceNames()
416 throw ( uno::RuntimeException, std::exception )
418 return impl_staticGetSupportedServiceNames();
421 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */