Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <com/sun/star/embed/ElementModes.hpp>
21 : #include <com/sun/star/embed/EntryInitModes.hpp>
22 : #include <com/sun/star/document/XTypeDetection.hpp>
23 : #include <com/sun/star/beans/PropertyValue.hpp>
24 : #include <com/sun/star/beans/XPropertySet.hpp>
25 : #include <com/sun/star/container/XNameAccess.hpp>
26 :
27 : #include <comphelper/processfactory.hxx>
28 : #include <cppuhelper/supportsservice.hxx>
29 : #include <comphelper/documentconstants.hxx>
30 :
31 : #include "xfactory.hxx"
32 : #include "commonembobj.hxx"
33 : #include "specialobject.hxx"
34 : #include "oleembobj.hxx"
35 :
36 :
37 : using namespace ::com::sun::star;
38 :
39 32 : uno::Sequence< OUString > SAL_CALL OOoEmbeddedObjectFactory::impl_staticGetSupportedServiceNames()
40 : {
41 32 : uno::Sequence< OUString > aRet(2);
42 32 : aRet[0] = "com.sun.star.embed.OOoEmbeddedObjectFactory";
43 32 : aRet[1] = "com.sun.star.comp.embed.OOoEmbeddedObjectFactory";
44 32 : return aRet;
45 : }
46 :
47 97 : OUString SAL_CALL OOoEmbeddedObjectFactory::impl_staticGetImplementationName()
48 : {
49 97 : return OUString("com.sun.star.comp.embed.OOoEmbeddedObjectFactory");
50 : }
51 :
52 31 : uno::Reference< uno::XInterface > SAL_CALL OOoEmbeddedObjectFactory::impl_staticCreateSelfInstance(
53 : const uno::Reference< lang::XMultiServiceFactory >& xServiceManager )
54 : {
55 31 : return uno::Reference< uno::XInterface >( *new OOoEmbeddedObjectFactory( comphelper::getComponentContext(xServiceManager) ) );
56 : }
57 :
58 54 : uno::Reference< uno::XInterface > SAL_CALL OOoEmbeddedObjectFactory::createInstanceInitFromEntry(
59 : const uno::Reference< embed::XStorage >& xStorage,
60 : const OUString& sEntName,
61 : const uno::Sequence< beans::PropertyValue >& aMediaDescr,
62 : const uno::Sequence< beans::PropertyValue >& lObjArgs )
63 : throw ( lang::IllegalArgumentException,
64 : container::NoSuchElementException,
65 : io::IOException,
66 : uno::Exception,
67 : uno::RuntimeException, std::exception)
68 : {
69 54 : if ( !xStorage.is() )
70 : throw lang::IllegalArgumentException( "No parent storage is provided!",
71 : static_cast< ::cppu::OWeakObject* >(this),
72 0 : 1 );
73 :
74 54 : if ( sEntName.isEmpty() )
75 : throw lang::IllegalArgumentException( "Empty element name is provided!",
76 : static_cast< ::cppu::OWeakObject* >(this),
77 0 : 2 );
78 :
79 54 : uno::Reference< container::XNameAccess > xNameAccess( xStorage, uno::UNO_QUERY );
80 54 : if ( !xNameAccess.is() )
81 0 : throw uno::RuntimeException(); //TODO
82 :
83 : // detect entry existence
84 54 : if ( !xNameAccess->hasByName( sEntName ) )
85 0 : throw container::NoSuchElementException();
86 :
87 54 : uno::Reference< uno::XInterface > xResult;
88 54 : if ( xStorage->isStorageElement( sEntName ) )
89 : {
90 : // the object must be based on storage
91 : uno::Reference< embed::XStorage > xSubStorage =
92 54 : xStorage->openStorageElement( sEntName, embed::ElementModes::READ );
93 :
94 108 : uno::Reference< beans::XPropertySet > xPropSet( xSubStorage, uno::UNO_QUERY );
95 54 : if ( !xPropSet.is() )
96 0 : throw uno::RuntimeException();
97 :
98 108 : OUString aMediaType;
99 : try {
100 54 : uno::Any aAny = xPropSet->getPropertyValue("MediaType");
101 54 : aAny >>= aMediaType;
102 : }
103 0 : catch ( const uno::Exception& )
104 : {
105 : }
106 :
107 : try {
108 54 : uno::Reference< lang::XComponent > xComp( xSubStorage, uno::UNO_QUERY );
109 54 : if ( xComp.is() )
110 54 : xComp->dispose();
111 : }
112 0 : catch ( const uno::Exception& )
113 : {
114 : }
115 54 : xSubStorage = uno::Reference< embed::XStorage >();
116 :
117 108 : uno::Sequence< beans::NamedValue > aObject = m_aConfigHelper.GetObjectPropsByMediaType( aMediaType );
118 :
119 : // If the sequence is empty, fall back to the FileFormatVersion=6200 filter, Base only has that.
120 54 : if (!aObject.hasElements() && aMediaType == MIMETYPE_OASIS_OPENDOCUMENT_DATABASE_ASCII)
121 0 : aObject = m_aConfigHelper.GetObjectPropsByMediaType(MIMETYPE_VND_SUN_XML_BASE_ASCII);
122 :
123 54 : if ( !aObject.getLength() )
124 0 : throw io::IOException(); // unexpected mimetype of the storage
125 :
126 108 : xResult = uno::Reference< uno::XInterface >(
127 : static_cast< ::cppu::OWeakObject* > ( new OCommonEmbeddedObject(
128 : m_xContext,
129 54 : aObject ) ),
130 108 : uno::UNO_QUERY );
131 : }
132 : else
133 : {
134 : // the object must be OOo embedded object, if it is not an exception must be thrown
135 0 : throw io::IOException(); // TODO:
136 : }
137 :
138 108 : uno::Reference< embed::XEmbedPersist > xPersist( xResult, uno::UNO_QUERY );
139 :
140 54 : if ( !xPersist.is() )
141 0 : throw uno::RuntimeException(); // TODO: the interface must be supported by own document objects
142 :
143 54 : xPersist->setPersistentEntry( xStorage,
144 : sEntName,
145 : embed::EntryInitModes::DEFAULT_INIT,
146 : aMediaDescr,
147 54 : lObjArgs );
148 :
149 108 : return xResult;
150 : }
151 :
152 17 : uno::Reference< uno::XInterface > SAL_CALL OOoEmbeddedObjectFactory::createInstanceInitFromMediaDescriptor(
153 : const uno::Reference< embed::XStorage >& xStorage,
154 : const OUString& sEntName,
155 : const uno::Sequence< beans::PropertyValue >& aMediaDescr,
156 : const uno::Sequence< beans::PropertyValue >& lObjArgs )
157 : throw ( lang::IllegalArgumentException,
158 : io::IOException,
159 : uno::Exception,
160 : uno::RuntimeException, std::exception)
161 : {
162 17 : if ( !xStorage.is() )
163 : throw lang::IllegalArgumentException( "No parent storage is provided!",
164 : static_cast< ::cppu::OWeakObject* >(this),
165 0 : 1 );
166 :
167 17 : if ( sEntName.isEmpty() )
168 : throw lang::IllegalArgumentException( "Empty element name is provided!",
169 : static_cast< ::cppu::OWeakObject* >(this),
170 0 : 2 );
171 :
172 17 : uno::Sequence< beans::PropertyValue > aTempMedDescr( aMediaDescr );
173 :
174 : // check if there is FilterName
175 34 : OUString aFilterName = m_aConfigHelper.UpdateMediaDescriptorWithFilterName( aTempMedDescr, false );
176 :
177 17 : uno::Reference< uno::XInterface > xResult;
178 :
179 : // find document service name
180 17 : if ( !aFilterName.isEmpty() )
181 : {
182 17 : uno::Sequence< beans::NamedValue > aObject = m_aConfigHelper.GetObjectPropsByFilter( aFilterName );
183 17 : if ( !aObject.getLength() )
184 0 : throw io::IOException(); // unexpected mimetype of the storage
185 :
186 :
187 34 : xResult = uno::Reference< uno::XInterface >(
188 : static_cast< ::cppu::OWeakObject* > ( new OCommonEmbeddedObject(
189 : m_xContext,
190 17 : aObject ) ),
191 34 : uno::UNO_QUERY );
192 : }
193 : else
194 : {
195 : // the object must be OOo embedded object, if it is not an exception must be thrown
196 0 : throw io::IOException(); // TODO:
197 : }
198 :
199 34 : uno::Reference< embed::XEmbedPersist > xPersist( xResult, uno::UNO_QUERY );
200 :
201 17 : if ( !xPersist.is() )
202 0 : throw uno::RuntimeException(); // TODO: the interface must be supported ( what about applets? )
203 :
204 17 : xPersist->setPersistentEntry( xStorage,
205 : sEntName,
206 : embed::EntryInitModes::MEDIA_DESCRIPTOR_INIT,
207 : aTempMedDescr,
208 17 : lObjArgs );
209 :
210 30 : return xResult;
211 : }
212 :
213 499 : uno::Reference< uno::XInterface > SAL_CALL OOoEmbeddedObjectFactory::createInstanceInitNew(
214 : const uno::Sequence< sal_Int8 >& aClassID,
215 : const OUString& /*aClassName*/,
216 : const uno::Reference< embed::XStorage >& xStorage,
217 : const OUString& sEntName,
218 : const uno::Sequence< beans::PropertyValue >& lObjArgs )
219 : throw ( lang::IllegalArgumentException,
220 : io::IOException,
221 : uno::Exception,
222 : uno::RuntimeException, std::exception)
223 : {
224 499 : uno::Reference< uno::XInterface > xResult;
225 :
226 499 : if ( !xStorage.is() )
227 : throw lang::IllegalArgumentException( "No parent storage is provided!",
228 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
229 0 : 3 );
230 :
231 499 : if ( sEntName.isEmpty() )
232 : throw lang::IllegalArgumentException( "Empty element name is provided!",
233 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
234 0 : 4 );
235 :
236 998 : uno::Sequence< beans::NamedValue > aObject = m_aConfigHelper.GetObjectPropsByClassID( aClassID );
237 499 : if ( !aObject.getLength() )
238 0 : throw io::IOException(); // unexpected mimetype of the storage
239 :
240 998 : xResult = uno::Reference< uno::XInterface >(
241 : static_cast< ::cppu::OWeakObject* > ( new OCommonEmbeddedObject(
242 : m_xContext,
243 499 : aObject ) ),
244 499 : uno::UNO_QUERY );
245 :
246 :
247 998 : uno::Reference< embed::XEmbedPersist > xPersist( xResult, uno::UNO_QUERY );
248 :
249 499 : if ( !xPersist.is() )
250 0 : throw uno::RuntimeException(); // TODO: the interface must be supported by own document objects
251 :
252 499 : xPersist->setPersistentEntry( xStorage,
253 : sEntName,
254 : embed::EntryInitModes::TRUNCATE_INIT,
255 : uno::Sequence< beans::PropertyValue >(),
256 499 : lObjArgs );
257 :
258 998 : return xResult;
259 : }
260 :
261 0 : uno::Reference< uno::XInterface > SAL_CALL OOoEmbeddedObjectFactory::createInstanceUserInit(
262 : const uno::Sequence< sal_Int8 >& aClassID,
263 : const OUString& /*aClassName*/,
264 : const uno::Reference< embed::XStorage >& xStorage,
265 : const OUString& sEntName,
266 : sal_Int32 nEntryConnectionMode,
267 : const uno::Sequence< beans::PropertyValue >& lArguments,
268 : const uno::Sequence< beans::PropertyValue >& lObjArgs )
269 : throw ( lang::IllegalArgumentException,
270 : io::IOException,
271 : uno::Exception,
272 : uno::RuntimeException, std::exception )
273 : {
274 : // the initialization is completelly controlled by user
275 0 : if ( !xStorage.is() )
276 : throw lang::IllegalArgumentException( "No parent storage is provided!",
277 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
278 0 : 1 );
279 :
280 0 : if ( sEntName.isEmpty() )
281 : throw lang::IllegalArgumentException( "Empty element name is provided!",
282 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
283 0 : 2 );
284 :
285 0 : uno::Sequence< beans::NamedValue > aObject = m_aConfigHelper.GetObjectPropsByClassID( aClassID );
286 0 : if ( !aObject.getLength() )
287 0 : throw io::IOException(); // unexpected mimetype of the storage
288 :
289 0 : uno::Sequence< beans::PropertyValue > aTempMedDescr( lArguments );
290 0 : if ( nEntryConnectionMode == embed::EntryInitModes::MEDIA_DESCRIPTOR_INIT )
291 : {
292 0 : OUString aFilterName = m_aConfigHelper.UpdateMediaDescriptorWithFilterName( aTempMedDescr, aObject );
293 0 : if ( aFilterName.isEmpty() )
294 : // the object must be OOo embedded object, if it is not an exception must be thrown
295 0 : throw io::IOException(); // TODO:
296 : }
297 :
298 : uno::Reference< uno::XInterface > xResult = uno::Reference< uno::XInterface > (
299 : static_cast< ::cppu::OWeakObject* > ( new OCommonEmbeddedObject(
300 : m_xContext,
301 0 : aObject ) ),
302 0 : uno::UNO_QUERY );
303 :
304 0 : uno::Reference< embed::XEmbedPersist > xPersist( xResult, uno::UNO_QUERY );
305 0 : if ( xPersist.is() )
306 : {
307 0 : xPersist->setPersistentEntry( xStorage,
308 : sEntName,
309 : nEntryConnectionMode,
310 : aTempMedDescr,
311 0 : lObjArgs );
312 :
313 : }
314 : else
315 0 : throw uno::RuntimeException(); // TODO:
316 :
317 0 : return xResult;
318 : }
319 :
320 0 : uno::Reference< uno::XInterface > SAL_CALL OOoEmbeddedObjectFactory::createInstanceLink(
321 : const uno::Reference< embed::XStorage >& /*xStorage*/,
322 : const OUString& /*sEntName*/,
323 : const uno::Sequence< beans::PropertyValue >& aMediaDescr,
324 : const uno::Sequence< beans::PropertyValue >& lObjArgs )
325 : throw ( lang::IllegalArgumentException,
326 : io::IOException,
327 : uno::Exception,
328 : uno::RuntimeException, std::exception )
329 : {
330 0 : uno::Reference< uno::XInterface > xResult;
331 :
332 0 : uno::Sequence< beans::PropertyValue > aTempMedDescr( aMediaDescr );
333 :
334 : // check if there is URL, URL must exist
335 0 : OUString aURL;
336 0 : for ( sal_Int32 nInd = 0; nInd < aTempMedDescr.getLength(); nInd++ )
337 0 : if ( aTempMedDescr[nInd].Name == "URL" )
338 0 : aTempMedDescr[nInd].Value >>= aURL;
339 :
340 0 : if ( aURL.isEmpty() )
341 : throw lang::IllegalArgumentException( "No URL for the link is provided!",
342 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
343 0 : 3 );
344 :
345 0 : OUString aFilterName = m_aConfigHelper.UpdateMediaDescriptorWithFilterName( aTempMedDescr, false );
346 :
347 0 : if ( !aFilterName.isEmpty() )
348 : {
349 0 : uno::Sequence< beans::NamedValue > aObject = m_aConfigHelper.GetObjectPropsByFilter( aFilterName );
350 0 : if ( !aObject.getLength() )
351 0 : throw io::IOException(); // unexpected mimetype of the storage
352 :
353 :
354 0 : xResult = uno::Reference< uno::XInterface >(
355 : static_cast< ::cppu::OWeakObject* > ( new OCommonEmbeddedObject(
356 : m_xContext,
357 : aObject,
358 : aTempMedDescr,
359 0 : lObjArgs ) ),
360 0 : uno::UNO_QUERY );
361 : }
362 : else
363 : {
364 : // the object must be OOo embedded object, if it is not an exception must be thrown
365 0 : throw io::IOException(); // TODO:
366 : }
367 :
368 0 : return xResult;
369 : }
370 :
371 0 : uno::Reference< uno::XInterface > SAL_CALL OOoEmbeddedObjectFactory::createInstanceLinkUserInit(
372 : const uno::Sequence< sal_Int8 >& aClassID,
373 : const OUString& /*aClassName*/,
374 : const uno::Reference< embed::XStorage >& xStorage,
375 : const OUString& sEntName,
376 : const uno::Sequence< beans::PropertyValue >& lArguments,
377 : const uno::Sequence< beans::PropertyValue >& lObjArgs )
378 : throw ( lang::IllegalArgumentException,
379 : io::IOException,
380 : uno::Exception,
381 : uno::RuntimeException )
382 : {
383 0 : uno::Reference< uno::XInterface > xResult;
384 :
385 : // the initialization is completelly controlled by user
386 0 : if ( !xStorage.is() )
387 : throw lang::IllegalArgumentException( "No parent storage is provided!",
388 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
389 0 : 1 );
390 :
391 0 : if ( sEntName.isEmpty() )
392 : throw lang::IllegalArgumentException( "Empty element name is provided!",
393 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
394 0 : 2 );
395 :
396 0 : uno::Sequence< beans::PropertyValue > aTempMedDescr( lArguments );
397 :
398 0 : OUString aURL;
399 0 : for ( sal_Int32 nInd = 0; nInd < aTempMedDescr.getLength(); nInd++ )
400 0 : if ( aTempMedDescr[nInd].Name == "URL" )
401 0 : aTempMedDescr[nInd].Value >>= aURL;
402 :
403 0 : if ( aURL.isEmpty() )
404 : throw lang::IllegalArgumentException( "No URL for the link is provided!",
405 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
406 0 : 3 );
407 :
408 0 : uno::Sequence< beans::NamedValue > aObject = m_aConfigHelper.GetObjectPropsByClassID( aClassID );
409 0 : if ( !aObject.getLength() )
410 0 : throw io::IOException(); // unexpected mimetype of the storage
411 :
412 0 : OUString aFilterName = m_aConfigHelper.UpdateMediaDescriptorWithFilterName( aTempMedDescr, aObject );
413 :
414 0 : if ( !aFilterName.isEmpty() )
415 : {
416 :
417 0 : xResult = uno::Reference< uno::XInterface >(
418 : static_cast< ::cppu::OWeakObject* > ( new OCommonEmbeddedObject(
419 : m_xContext,
420 : aObject,
421 : aTempMedDescr,
422 0 : lObjArgs ) ),
423 0 : uno::UNO_QUERY );
424 : }
425 : else
426 : {
427 : // the object must be OOo embedded object, if it is not an exception must be thrown
428 0 : throw io::IOException(); // TODO:
429 : }
430 :
431 0 : return xResult;
432 : }
433 :
434 1 : OUString SAL_CALL OOoEmbeddedObjectFactory::getImplementationName()
435 : throw ( uno::RuntimeException, std::exception )
436 : {
437 1 : return impl_staticGetImplementationName();
438 : }
439 :
440 0 : sal_Bool SAL_CALL OOoEmbeddedObjectFactory::supportsService( const OUString& ServiceName )
441 : throw ( uno::RuntimeException, std::exception )
442 : {
443 0 : return cppu::supportsService(this, ServiceName);
444 : }
445 :
446 1 : uno::Sequence< OUString > SAL_CALL OOoEmbeddedObjectFactory::getSupportedServiceNames()
447 : throw ( uno::RuntimeException, std::exception )
448 : {
449 1 : return impl_staticGetSupportedServiceNames();
450 : }
451 :
452 2 : uno::Sequence< OUString > SAL_CALL OOoSpecialEmbeddedObjectFactory::impl_staticGetSupportedServiceNames()
453 : {
454 2 : uno::Sequence< OUString > aRet(2);
455 2 : aRet[0] = "com.sun.star.embed.OOoSpecialEmbeddedObjectFactory";
456 2 : aRet[1] = "com.sun.star.comp.embed.OOoSpecialEmbeddedObjectFactory";
457 2 : return aRet;
458 : }
459 :
460 36 : OUString SAL_CALL OOoSpecialEmbeddedObjectFactory::impl_staticGetImplementationName()
461 : {
462 36 : return OUString("com.sun.star.comp.embed.OOoSpecialEmbeddedObjectFactory");
463 : }
464 :
465 2 : uno::Reference< uno::XInterface > SAL_CALL OOoSpecialEmbeddedObjectFactory::impl_staticCreateSelfInstance(
466 : const uno::Reference< lang::XMultiServiceFactory >& xServiceManager )
467 : {
468 2 : return uno::Reference< uno::XInterface >( *new OOoSpecialEmbeddedObjectFactory( comphelper::getComponentContext(xServiceManager) ) );
469 : }
470 :
471 8 : uno::Reference< uno::XInterface > SAL_CALL OOoSpecialEmbeddedObjectFactory::createInstanceUserInit(
472 : const uno::Sequence< sal_Int8 >& aClassID,
473 : const OUString& /*aClassName*/,
474 : const uno::Reference< embed::XStorage >& /*xStorage*/,
475 : const OUString& /*sEntName*/,
476 : sal_Int32 /*nEntryConnectionMode*/,
477 : const uno::Sequence< beans::PropertyValue >& /*lArguments*/,
478 : const uno::Sequence< beans::PropertyValue >& /*lObjArgs*/ )
479 : throw ( lang::IllegalArgumentException,
480 : io::IOException,
481 : uno::Exception,
482 : uno::RuntimeException, std::exception )
483 : {
484 8 : uno::Sequence< beans::NamedValue > aObject = m_aConfigHelper.GetObjectPropsByClassID( aClassID );
485 8 : if ( !aObject.getLength() )
486 0 : throw io::IOException(); // unexpected mimetype of the storage
487 :
488 : uno::Reference< uno::XInterface > xResult(
489 : static_cast< ::cppu::OWeakObject* > ( new OSpecialEmbeddedObject(
490 : m_xContext,
491 8 : aObject ) ),
492 8 : uno::UNO_QUERY );
493 8 : return xResult;
494 : }
495 :
496 0 : OUString SAL_CALL OOoSpecialEmbeddedObjectFactory::getImplementationName()
497 : throw ( uno::RuntimeException, std::exception )
498 : {
499 0 : return impl_staticGetImplementationName();
500 : }
501 :
502 0 : sal_Bool SAL_CALL OOoSpecialEmbeddedObjectFactory::supportsService( const OUString& ServiceName )
503 : throw ( uno::RuntimeException, std::exception )
504 : {
505 0 : return cppu::supportsService(this, ServiceName);
506 : }
507 :
508 0 : uno::Sequence< OUString > SAL_CALL OOoSpecialEmbeddedObjectFactory::getSupportedServiceNames()
509 : throw ( uno::RuntimeException, std::exception )
510 : {
511 0 : return impl_staticGetSupportedServiceNames();
512 : }
513 :
514 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|