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 <oleembobj.hxx>
21 : #include <com/sun/star/embed/EmbedStates.hpp>
22 : #include <com/sun/star/embed/EmbedVerbs.hpp>
23 : #include <com/sun/star/embed/EntryInitModes.hpp>
24 : #include <com/sun/star/embed/XStorage.hpp>
25 : #include <com/sun/star/embed/ElementModes.hpp>
26 : #include <com/sun/star/embed/EmbedUpdateModes.hpp>
27 : #include <com/sun/star/embed/Aspects.hpp>
28 : #include <com/sun/star/embed/NeedsRunningStateException.hpp>
29 : #include <com/sun/star/embed/StateChangeInProgressException.hpp>
30 : #include <com/sun/star/embed/EmbedMisc.hpp>
31 : #include <com/sun/star/embed/XEmbedObjectCreator.hpp>
32 : #include <com/sun/star/io/TempFile.hpp>
33 : #include <com/sun/star/io/XSeekable.hpp>
34 : #include <com/sun/star/lang/DisposedException.hpp>
35 : #include <com/sun/star/beans/NamedValue.hpp>
36 : #include <com/sun/star/beans/XPropertySet.hpp>
37 : #include <com/sun/star/frame/XLoadable.hpp>
38 : #include <com/sun/star/document/XStorageBasedDocument.hpp>
39 : #include <com/sun/star/ucb/SimpleFileAccess.hpp>
40 : #include <com/sun/star/container/XNameAccess.hpp>
41 : #include <com/sun/star/container/XNameContainer.hpp>
42 : #include <com/sun/star/system/SystemShellExecute.hpp>
43 : #include <com/sun/star/system/SystemShellExecuteFlags.hpp>
44 :
45 : #include <rtl/logfile.hxx>
46 : #include <cppuhelper/interfacecontainer.h>
47 : #include <comphelper/processfactory.hxx>
48 : #include <comphelper/mimeconfighelper.hxx>
49 : #include <comphelper/storagehelper.hxx>
50 :
51 :
52 : #include <targetstatecontrol.hxx>
53 :
54 : #include <olecomponent.hxx>
55 :
56 : #include "ownview.hxx"
57 :
58 : using namespace ::com::sun::star;
59 :
60 : #ifdef WNT
61 : //----------------------------------------------
62 : void OleEmbeddedObject::SwitchComponentToRunningState_Impl()
63 : {
64 : if ( m_pOleComponent )
65 : {
66 : try
67 : {
68 : m_pOleComponent->RunObject();
69 : }
70 : catch( const embed::UnreachableStateException& )
71 : {
72 : GetRidOfComponent();
73 : throw;
74 : }
75 : catch( const embed::WrongStateException& )
76 : {
77 : GetRidOfComponent();
78 : throw;
79 : }
80 : }
81 : else
82 : {
83 : throw embed::UnreachableStateException();
84 : }
85 : }
86 :
87 : //----------------------------------------------
88 : uno::Sequence< sal_Int32 > OleEmbeddedObject::GetReachableStatesList_Impl(
89 : const uno::Sequence< embed::VerbDescriptor >& aVerbList )
90 : {
91 : uno::Sequence< sal_Int32 > aStates(2);
92 : aStates[0] = embed::EmbedStates::LOADED;
93 : aStates[1] = embed::EmbedStates::RUNNING;
94 : for ( sal_Int32 nInd = 0; nInd < aVerbList.getLength(); nInd++ )
95 : if ( aVerbList[nInd].VerbID == embed::EmbedVerbs::MS_OLEVERB_OPEN )
96 : {
97 : aStates.realloc(3);
98 : aStates[2] = embed::EmbedStates::ACTIVE;
99 : }
100 :
101 : return aStates;
102 : }
103 :
104 : //----------------------------------------------
105 : uno::Sequence< sal_Int32 > OleEmbeddedObject::GetIntermediateVerbsSequence_Impl( sal_Int32 nNewState )
106 : {
107 : OSL_ENSURE( m_nObjectState != embed::EmbedStates::LOADED, "Loaded object is switched to running state without verbs using!" );
108 :
109 : // actually there will be only one verb
110 : if ( m_nObjectState == embed::EmbedStates::RUNNING && nNewState == embed::EmbedStates::ACTIVE )
111 : {
112 : uno::Sequence< sal_Int32 > aVerbs( 1 );
113 : aVerbs[0] = embed::EmbedVerbs::MS_OLEVERB_OPEN;
114 : }
115 :
116 : return uno::Sequence< sal_Int32 >();
117 : }
118 : #endif
119 : //----------------------------------------------
120 0 : void OleEmbeddedObject::MoveListeners()
121 : {
122 0 : if ( m_pInterfaceContainer )
123 : {
124 : // move state change listeners
125 : {
126 : ::cppu::OInterfaceContainerHelper* pStateChangeContainer =
127 0 : m_pInterfaceContainer->getContainer( ::getCppuType( ( const uno::Reference< embed::XStateChangeListener >*) NULL ) );
128 0 : if ( pStateChangeContainer != NULL )
129 : {
130 0 : uno::Reference< embed::XStateChangeBroadcaster > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
131 0 : if ( xWrappedObject.is() )
132 : {
133 0 : ::cppu::OInterfaceIteratorHelper pIterator( *pStateChangeContainer );
134 0 : while ( pIterator.hasMoreElements() )
135 : {
136 : try
137 : {
138 0 : xWrappedObject->addStateChangeListener( (embed::XStateChangeListener*)pIterator.next() );
139 : }
140 0 : catch( const uno::RuntimeException& )
141 : {
142 0 : pIterator.remove();
143 : }
144 0 : }
145 0 : }
146 : }
147 : }
148 :
149 : // move event listeners
150 : {
151 : ::cppu::OInterfaceContainerHelper* pEventContainer =
152 0 : m_pInterfaceContainer->getContainer( ::getCppuType( ( const uno::Reference< document::XEventListener >*) NULL ) );
153 0 : if ( pEventContainer != NULL )
154 : {
155 0 : uno::Reference< document::XEventBroadcaster > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
156 0 : if ( xWrappedObject.is() )
157 : {
158 0 : ::cppu::OInterfaceIteratorHelper pIterator( *pEventContainer );
159 0 : while ( pIterator.hasMoreElements() )
160 : {
161 : try
162 : {
163 0 : xWrappedObject->addEventListener( (document::XEventListener*)pIterator.next() );
164 : }
165 0 : catch( const uno::RuntimeException& )
166 : {
167 0 : pIterator.remove();
168 : }
169 0 : }
170 0 : }
171 : }
172 : }
173 :
174 : // move close listeners
175 : {
176 : ::cppu::OInterfaceContainerHelper* pCloseContainer =
177 0 : m_pInterfaceContainer->getContainer( ::getCppuType( ( const uno::Reference< util::XCloseListener >*) NULL ) );
178 0 : if ( pCloseContainer != NULL )
179 : {
180 0 : uno::Reference< util::XCloseBroadcaster > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
181 0 : if ( xWrappedObject.is() )
182 : {
183 0 : ::cppu::OInterfaceIteratorHelper pIterator( *pCloseContainer );
184 0 : while ( pIterator.hasMoreElements() )
185 : {
186 : try
187 : {
188 0 : xWrappedObject->addCloseListener( (util::XCloseListener*)pIterator.next() );
189 : }
190 0 : catch( const uno::RuntimeException& )
191 : {
192 0 : pIterator.remove();
193 : }
194 0 : }
195 0 : }
196 : }
197 : }
198 :
199 0 : delete m_pInterfaceContainer;
200 0 : m_pInterfaceContainer = NULL;
201 : }
202 0 : }
203 :
204 : //----------------------------------------------
205 0 : uno::Reference< embed::XStorage > OleEmbeddedObject::CreateTemporarySubstorage( ::rtl::OUString& o_aStorageName )
206 : {
207 0 : uno::Reference< embed::XStorage > xResult;
208 :
209 0 : for ( sal_Int32 nInd = 0; nInd < 32000 && !xResult.is(); nInd++ )
210 : {
211 0 : ::rtl::OUString aName = ::rtl::OUString::valueOf( nInd );
212 0 : aName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TMPSTOR" ) );
213 0 : aName += m_aEntryName;
214 0 : if ( !m_xParentStorage->hasByName( aName ) )
215 : {
216 0 : xResult = m_xParentStorage->openStorageElement( aName, embed::ElementModes::READWRITE );
217 0 : o_aStorageName = aName;
218 : }
219 0 : }
220 :
221 0 : if ( !xResult.is() )
222 : {
223 0 : o_aStorageName = ::rtl::OUString();
224 0 : throw uno::RuntimeException();
225 : }
226 :
227 0 : return xResult;
228 : }
229 :
230 : //----------------------------------------------
231 0 : ::rtl::OUString OleEmbeddedObject::MoveToTemporarySubstream()
232 : {
233 0 : ::rtl::OUString aResult;
234 0 : for ( sal_Int32 nInd = 0; nInd < 32000 && aResult.isEmpty(); nInd++ )
235 : {
236 0 : ::rtl::OUString aName = ::rtl::OUString::valueOf( nInd );
237 0 : aName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TMPSTREAM" ) );
238 0 : aName += m_aEntryName;
239 0 : if ( !m_xParentStorage->hasByName( aName ) )
240 : {
241 0 : m_xParentStorage->renameElement( m_aEntryName, aName );
242 0 : aResult = aName;
243 : }
244 0 : }
245 :
246 0 : if ( aResult.isEmpty() )
247 0 : throw uno::RuntimeException();
248 :
249 0 : return aResult;
250 : }
251 :
252 : //----------------------------------------------
253 0 : sal_Bool OleEmbeddedObject::TryToConvertToOOo()
254 : {
255 0 : sal_Bool bResult = sal_False;
256 :
257 0 : ::rtl::OUString aStorageName;
258 0 : ::rtl::OUString aTmpStreamName;
259 0 : sal_Int32 nStep = 0;
260 :
261 0 : if ( m_pOleComponent || m_bReadOnly )
262 0 : return sal_False;
263 :
264 : try
265 : {
266 0 : changeState( embed::EmbedStates::LOADED );
267 :
268 : // the stream must be seekable
269 0 : uno::Reference< io::XSeekable > xSeekable( m_xObjectStream, uno::UNO_QUERY_THROW );
270 0 : xSeekable->seek( 0 );
271 0 : ::rtl::OUString aFilterName = OwnView_Impl::GetFilterNameFromExtentionAndInStream( m_xFactory, ::rtl::OUString(), m_xObjectStream->getInputStream() );
272 :
273 : // use the solution only for OOXML format currently
274 0 : if ( !aFilterName.isEmpty()
275 0 : && ( aFilterName == "Calc MS Excel 2007 XML" || aFilterName == "Impress MS PowerPoint 2007 XML" || aFilterName == "MS Word 2007 XML" ) )
276 : {
277 : uno::Reference< container::XNameAccess > xFilterFactory(
278 0 : m_xFactory->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.FilterFactory" ) )),
279 0 : uno::UNO_QUERY_THROW );
280 :
281 0 : ::rtl::OUString aDocServiceName;
282 0 : uno::Any aFilterAnyData = xFilterFactory->getByName( aFilterName );
283 0 : uno::Sequence< beans::PropertyValue > aFilterData;
284 0 : if ( aFilterAnyData >>= aFilterData )
285 : {
286 0 : for ( sal_Int32 nInd = 0; nInd < aFilterData.getLength(); nInd++ )
287 0 : if ( aFilterData[nInd].Name == "DocumentService" )
288 0 : aFilterData[nInd].Value >>= aDocServiceName;
289 : }
290 :
291 0 : if ( !aDocServiceName.isEmpty() )
292 : {
293 : // create the model
294 0 : uno::Sequence< uno::Any > aArguments(1);
295 0 : aArguments[0] <<= beans::NamedValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "EmbeddedObject" ) ), uno::makeAny( (sal_Bool)sal_True ));
296 :
297 0 : uno::Reference< util::XCloseable > xDocument( m_xFactory->createInstanceWithArguments( aDocServiceName, aArguments ), uno::UNO_QUERY_THROW );
298 0 : uno::Reference< frame::XLoadable > xLoadable( xDocument, uno::UNO_QUERY_THROW );
299 0 : uno::Reference< document::XStorageBasedDocument > xStorDoc( xDocument, uno::UNO_QUERY_THROW );
300 :
301 : // let the model behave as embedded one
302 0 : uno::Reference< frame::XModel > xModel( xDocument, uno::UNO_QUERY_THROW );
303 0 : uno::Sequence< beans::PropertyValue > aSeq( 1 );
304 0 : aSeq[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "SetEmbedded" ));
305 0 : aSeq[0].Value <<= sal_True;
306 0 : xModel->attachResource( ::rtl::OUString(), aSeq );
307 :
308 : // load the model from the stream
309 0 : uno::Sequence< beans::PropertyValue > aArgs( 5 );
310 0 : aArgs[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "HierarchicalDocumentName" ));
311 0 : aArgs[0].Value <<= m_aEntryName;
312 0 : aArgs[1].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ReadOnly" ));
313 0 : aArgs[1].Value <<= sal_True;
314 0 : aArgs[2].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "FilterName" ));
315 0 : aArgs[2].Value <<= aFilterName;
316 0 : aArgs[3].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "URL" ));
317 0 : aArgs[3].Value <<= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "private:stream" ));
318 0 : aArgs[4].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "InputStream" ));
319 0 : aArgs[4].Value <<= m_xObjectStream->getInputStream();
320 :
321 0 : xSeekable->seek( 0 );
322 0 : xLoadable->load( aArgs );
323 :
324 : // the model is successfuly loaded, create a new storage and store the model to the storage
325 0 : uno::Reference< embed::XStorage > xTmpStorage = CreateTemporarySubstorage( aStorageName );
326 0 : xStorDoc->storeToStorage( xTmpStorage, uno::Sequence< beans::PropertyValue >() );
327 0 : xDocument->close( sal_True );
328 0 : uno::Reference< beans::XPropertySet > xStorProps( xTmpStorage, uno::UNO_QUERY_THROW );
329 0 : ::rtl::OUString aMediaType;
330 0 : xStorProps->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "MediaType" )) ) >>= aMediaType;
331 0 : xTmpStorage->dispose();
332 :
333 : // look for the related embedded object factory
334 0 : ::comphelper::MimeConfigurationHelper aConfigHelper( m_xFactory );
335 0 : ::rtl::OUString aEmbedFactory;
336 0 : if ( !aMediaType.isEmpty() )
337 0 : aEmbedFactory = aConfigHelper.GetFactoryNameByMediaType( aMediaType );
338 :
339 0 : if ( aEmbedFactory.isEmpty() )
340 0 : throw uno::RuntimeException();
341 :
342 0 : uno::Reference< uno::XInterface > xFact = m_xFactory->createInstance( aEmbedFactory );
343 :
344 0 : uno::Reference< embed::XEmbedObjectCreator > xEmbCreator( xFact, uno::UNO_QUERY_THROW );
345 :
346 : // now the object should be adjusted to become the wrapper
347 0 : nStep = 1;
348 0 : uno::Reference< lang::XComponent > xComp( m_xObjectStream, uno::UNO_QUERY_THROW );
349 0 : xComp->dispose();
350 0 : m_xObjectStream = uno::Reference< io::XStream >();
351 0 : m_nObjectState = -1;
352 :
353 0 : nStep = 2;
354 0 : aTmpStreamName = MoveToTemporarySubstream();
355 :
356 0 : nStep = 3;
357 0 : m_xParentStorage->renameElement( aStorageName, m_aEntryName );
358 :
359 0 : nStep = 4;
360 0 : m_xWrappedObject.set( xEmbCreator->createInstanceInitFromEntry( m_xParentStorage, m_aEntryName, uno::Sequence< beans::PropertyValue >(), uno::Sequence< beans::PropertyValue >() ), uno::UNO_QUERY_THROW );
361 :
362 0 : bResult = sal_True; // the change is no more revertable
363 : try
364 : {
365 0 : m_xParentStorage->removeElement( aTmpStreamName );
366 : }
367 0 : catch( const uno::Exception& )
368 : {
369 : // the success of the removing is not so important
370 0 : }
371 0 : }
372 0 : }
373 : }
374 0 : catch( const uno::Exception& )
375 : {
376 : // repair the object if necessary
377 0 : switch( nStep )
378 : {
379 : case 4:
380 : case 3:
381 0 : if ( !aTmpStreamName.isEmpty() && aTmpStreamName != m_aEntryName )
382 : try
383 : {
384 0 : if ( m_xParentStorage->hasByName( m_aEntryName ) )
385 0 : m_xParentStorage->removeElement( m_aEntryName );
386 0 : m_xParentStorage->renameElement( aTmpStreamName, m_aEntryName );
387 : }
388 0 : catch ( const uno::Exception& )
389 : {
390 : try {
391 0 : close( sal_True );
392 0 : } catch( const uno::Exception& ) {}
393 :
394 0 : m_xParentStorage->dispose(); // ??? the storage has information loss, it should be closed without commiting!
395 0 : throw uno::RuntimeException(); // the repairing is not possible
396 : }
397 : case 2:
398 : try
399 : {
400 0 : m_xObjectStream = m_xParentStorage->openStreamElement( m_aEntryName, m_bReadOnly ? embed::ElementModes::READ : embed::ElementModes::READWRITE );
401 0 : m_nObjectState = embed::EmbedStates::LOADED;
402 : }
403 0 : catch( const uno::Exception& )
404 : {
405 : try {
406 0 : close( sal_True );
407 0 : } catch( const uno::Exception& ) {}
408 :
409 0 : throw uno::RuntimeException(); // the repairing is not possible
410 : }
411 : // no break as designed!
412 :
413 : case 1:
414 : case 0:
415 0 : if ( !aStorageName.isEmpty() )
416 : try {
417 0 : m_xParentStorage->removeElement( aStorageName );
418 0 : } catch( const uno::Exception& ) { OSL_FAIL( "Can not remove temporary storage!" ); }
419 0 : break;
420 : }
421 : }
422 :
423 0 : if ( bResult )
424 : {
425 : // the conversion was done successfuly, now the additional initializations should happen
426 :
427 0 : MoveListeners();
428 0 : m_xWrappedObject->setClientSite( m_xClientSite );
429 0 : if ( m_xParent.is() )
430 : {
431 0 : uno::Reference< container::XChild > xChild( m_xWrappedObject, uno::UNO_QUERY );
432 0 : if ( xChild.is() )
433 0 : xChild->setParent( m_xParent );
434 : }
435 :
436 : }
437 :
438 0 : return bResult;
439 : }
440 :
441 : //----------------------------------------------
442 0 : void SAL_CALL OleEmbeddedObject::changeState( sal_Int32 nNewState )
443 : throw ( embed::UnreachableStateException,
444 : embed::WrongStateException,
445 : uno::Exception,
446 : uno::RuntimeException )
447 : {
448 : RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OleEmbeddedObject::changeState" );
449 :
450 : // begin wrapping related part ====================
451 0 : uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
452 0 : if ( xWrappedObject.is() )
453 : {
454 : // the object was converted to OOo embedded object, the current implementation is now only a wrapper
455 0 : xWrappedObject->changeState( nNewState );
456 : return;
457 : }
458 : // end wrapping related part ====================
459 :
460 0 : ::osl::ResettableMutexGuard aGuard( m_aMutex );
461 :
462 0 : if ( m_bDisposed )
463 0 : throw lang::DisposedException(); // TODO
464 :
465 0 : if ( m_nObjectState == -1 )
466 : throw embed::WrongStateException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object has no persistence!\n" )),
467 0 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
468 :
469 : // in case the object is already in requested state
470 0 : if ( m_nObjectState == nNewState )
471 : return;
472 :
473 : #ifdef WNT
474 : if ( m_pOleComponent )
475 : {
476 : if ( m_nTargetState != -1 )
477 : {
478 : // means that the object is currently trying to reach the target state
479 : throw embed::StateChangeInProgressException( ::rtl::OUString(),
480 : uno::Reference< uno::XInterface >(),
481 : m_nTargetState );
482 : }
483 :
484 : TargetStateControl_Impl aControl( m_nTargetState, nNewState );
485 :
486 : // TODO: additional verbs can be a problem, since nobody knows how the object
487 : // will behave after activation
488 :
489 : sal_Int32 nOldState = m_nObjectState;
490 : aGuard.clear();
491 : StateChangeNotification_Impl( sal_True, nOldState, nNewState );
492 : aGuard.reset();
493 :
494 : try
495 : {
496 : if ( nNewState == embed::EmbedStates::LOADED )
497 : {
498 : // This means just closing of the current object
499 : // If component can not be closed the object stays in loaded state
500 : // and it holds reference to "incomplete" component
501 : // If the object is switched to running state later
502 : // the component will become "complete"
503 :
504 : // the loaded state must be set before, because of notifications!
505 : m_nObjectState = nNewState;
506 :
507 : {
508 : VerbExecutionControllerGuard aVerbGuard( m_aVerbExecutionController );
509 : m_pOleComponent->CloseObject();
510 : }
511 :
512 : aGuard.clear();
513 : StateChangeNotification_Impl( sal_False, nOldState, m_nObjectState );
514 : aGuard.reset();
515 : }
516 : else if ( nNewState == embed::EmbedStates::RUNNING || nNewState == embed::EmbedStates::ACTIVE )
517 : {
518 : if ( m_nObjectState == embed::EmbedStates::LOADED )
519 : {
520 : // if the target object is in loaded state and a different state is specified
521 : // as a new one the object first must be switched to running state.
522 :
523 : // the component can exist already in nonrunning state
524 : // it can be created during loading to detect type of object
525 : CreateOleComponentAndLoad_Impl( m_pOleComponent );
526 :
527 : SwitchComponentToRunningState_Impl();
528 : m_nObjectState = embed::EmbedStates::RUNNING;
529 : aGuard.clear();
530 : StateChangeNotification_Impl( sal_False, nOldState, m_nObjectState );
531 : aGuard.reset();
532 :
533 : if ( m_pOleComponent && m_bHasSizeToSet )
534 : {
535 : aGuard.clear();
536 : try {
537 : m_pOleComponent->SetExtent( m_aSizeToSet, m_nAspectToSet );
538 : m_bHasSizeToSet = sal_False;
539 : }
540 : catch( const uno::Exception& ) {}
541 : aGuard.reset();
542 : }
543 :
544 : if ( m_nObjectState == nNewState )
545 : return;
546 : }
547 :
548 : // so now the object is either switched from Active to Running state or vise versa
549 : // the notification about object state change will be done asynchronously
550 : if ( m_nObjectState == embed::EmbedStates::RUNNING && nNewState == embed::EmbedStates::ACTIVE )
551 : {
552 : // execute OPEN verb, if object does not reach active state it is an object's problem
553 : aGuard.clear();
554 : m_pOleComponent->ExecuteVerb( embed::EmbedVerbs::MS_OLEVERB_OPEN );
555 : aGuard.reset();
556 :
557 : // some objects do not allow to set the size even in running state
558 : if ( m_pOleComponent && m_bHasSizeToSet )
559 : {
560 : aGuard.clear();
561 : try {
562 : m_pOleComponent->SetExtent( m_aSizeToSet, m_nAspectToSet );
563 : m_bHasSizeToSet = sal_False;
564 : }
565 : catch( uno::Exception& ) {}
566 : aGuard.reset();
567 : }
568 :
569 : m_nObjectState = nNewState;
570 : }
571 : else if ( m_nObjectState == embed::EmbedStates::ACTIVE && nNewState == embed::EmbedStates::RUNNING )
572 : {
573 : aGuard.clear();
574 : m_pOleComponent->CloseObject();
575 : m_pOleComponent->RunObject(); // Should not fail, the object already was active
576 : aGuard.reset();
577 : m_nObjectState = nNewState;
578 : }
579 : else
580 : {
581 : throw embed::UnreachableStateException();
582 : }
583 : }
584 : else
585 : throw embed::UnreachableStateException();
586 : }
587 : catch( uno::Exception& )
588 : {
589 : aGuard.clear();
590 : StateChangeNotification_Impl( sal_False, nOldState, m_nObjectState );
591 : throw;
592 : }
593 : }
594 : else
595 : #endif
596 : {
597 0 : throw embed::UnreachableStateException();
598 0 : }
599 : }
600 :
601 : //----------------------------------------------
602 0 : uno::Sequence< sal_Int32 > SAL_CALL OleEmbeddedObject::getReachableStates()
603 : throw ( embed::WrongStateException,
604 : uno::RuntimeException )
605 : {
606 : RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OleEmbeddedObject::getReachableStates" );
607 :
608 : // begin wrapping related part ====================
609 0 : uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
610 0 : if ( xWrappedObject.is() )
611 : {
612 : // the object was converted to OOo embedded object, the current implementation is now only a wrapper
613 0 : return xWrappedObject->getReachableStates();
614 : }
615 : // end wrapping related part ====================
616 :
617 0 : ::osl::MutexGuard aGuard( m_aMutex );
618 0 : if ( m_bDisposed )
619 0 : throw lang::DisposedException(); // TODO
620 :
621 0 : if ( m_nObjectState == -1 )
622 : throw embed::WrongStateException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object has no persistence!\n" )),
623 0 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
624 :
625 : #ifdef WNT
626 : if ( m_pOleComponent )
627 : {
628 : if ( m_nObjectState == embed::EmbedStates::LOADED )
629 : {
630 : // the list of supported verbs can be retrieved only when object is in running state
631 : throw embed::NeedsRunningStateException(); // TODO:
632 : }
633 :
634 : // the list of states can only be guessed based on standard verbs,
635 : // since there is no way to detect what additional verbs do
636 : return GetReachableStatesList_Impl( m_pOleComponent->GetVerbList() );
637 : }
638 : else
639 : #endif
640 : {
641 0 : return uno::Sequence< sal_Int32 >();
642 0 : }
643 : }
644 :
645 : //----------------------------------------------
646 0 : sal_Int32 SAL_CALL OleEmbeddedObject::getCurrentState()
647 : throw ( embed::WrongStateException,
648 : uno::RuntimeException )
649 : {
650 : // begin wrapping related part ====================
651 0 : uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
652 0 : if ( xWrappedObject.is() )
653 : {
654 : // the object was converted to OOo embedded object, the current implementation is now only a wrapper
655 0 : return xWrappedObject->getCurrentState();
656 : }
657 : // end wrapping related part ====================
658 :
659 0 : ::osl::MutexGuard aGuard( m_aMutex );
660 0 : if ( m_bDisposed )
661 0 : throw lang::DisposedException(); // TODO
662 :
663 0 : if ( m_nObjectState == -1 )
664 : throw embed::WrongStateException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object has no persistence!\n" )),
665 0 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
666 :
667 : // TODO: Shouldn't we ask object? ( I guess no )
668 0 : return m_nObjectState;
669 : }
670 :
671 : namespace
672 : {
673 0 : bool lcl_CopyStream(uno::Reference<io::XInputStream> xIn, uno::Reference<io::XOutputStream> xOut)
674 : {
675 0 : const sal_Int32 nChunkSize = 4096;
676 0 : uno::Sequence< sal_Int8 > aData(nChunkSize);
677 0 : sal_Int32 nTotalRead = 0;
678 : sal_Int32 nRead;
679 0 : do
680 : {
681 0 : nRead = xIn->readBytes(aData, nChunkSize);
682 0 : nTotalRead += nRead;
683 0 : xOut->writeBytes(aData);
684 : } while (nRead == nChunkSize);
685 0 : return nTotalRead != 0;
686 : }
687 :
688 : //Dump the objects content to a tempfile, just the "CONTENTS" stream if
689 : //there is one for non-compound documents, otherwise the whole content.
690 : //On success a file is returned which must be removed by the caller
691 0 : rtl::OUString lcl_ExtractObject(::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xFactory,
692 : ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream > xObjectStream)
693 : {
694 0 : rtl::OUString sUrl;
695 :
696 : // the solution is only active for Unix systems
697 : #ifndef WNT
698 : uno::Reference <beans::XPropertySet> xNativeTempFile(
699 : io::TempFile::create(comphelper::getComponentContext(xFactory)),
700 0 : uno::UNO_QUERY_THROW);
701 0 : uno::Reference < io::XStream > xStream(xNativeTempFile, uno::UNO_QUERY_THROW);
702 :
703 0 : uno::Sequence< uno::Any > aArgs( 2 );
704 0 : aArgs[0] <<= xObjectStream;
705 0 : aArgs[1] <<= (sal_Bool)sal_True; // do not create copy
706 : uno::Reference< container::XNameContainer > xNameContainer(
707 0 : xFactory->createInstanceWithArguments(
708 : ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.OLESimpleStorage")),
709 0 : aArgs ), uno::UNO_QUERY_THROW );
710 :
711 0 : uno::Reference< io::XStream > xCONTENTS;
712 0 : xNameContainer->getByName(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CONTENTS"))) >>= xCONTENTS;
713 :
714 0 : sal_Bool bCopied = xCONTENTS.is() && lcl_CopyStream(xCONTENTS->getInputStream(), xStream->getOutputStream());
715 :
716 0 : uno::Reference< io::XSeekable > xSeekableStor(xObjectStream, uno::UNO_QUERY);
717 0 : if (xSeekableStor.is())
718 0 : xSeekableStor->seek(0);
719 :
720 0 : if (!bCopied)
721 0 : bCopied = lcl_CopyStream(xObjectStream->getInputStream(), xStream->getOutputStream());
722 :
723 0 : if (bCopied)
724 : {
725 0 : xNativeTempFile->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("RemoveFile")),
726 0 : uno::makeAny(sal_False));
727 0 : uno::Any aUrl = xNativeTempFile->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Uri")));
728 0 : aUrl >>= sUrl;
729 :
730 0 : xNativeTempFile = uno::Reference<beans::XPropertySet>();
731 :
732 : uno::Reference < ucb::XSimpleFileAccess3 > xSimpleFileAccess(
733 0 : ucb::SimpleFileAccess::create( comphelper::getComponentContext(xFactory) ) );
734 :
735 0 : xSimpleFileAccess->setReadOnly(sUrl, sal_True);
736 : }
737 : else
738 : {
739 0 : xNativeTempFile->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("RemoveFile")),
740 0 : uno::makeAny(sal_True));
741 : }
742 : #else
743 : (void) xFactory;
744 : (void) xObjectStream;
745 : #endif
746 0 : return sUrl;
747 : }
748 : }
749 :
750 : //----------------------------------------------
751 0 : void SAL_CALL OleEmbeddedObject::doVerb( sal_Int32 nVerbID )
752 : throw ( lang::IllegalArgumentException,
753 : embed::WrongStateException,
754 : embed::UnreachableStateException,
755 : uno::Exception,
756 : uno::RuntimeException )
757 : {
758 : RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OleEmbeddedObject::doVerb" );
759 :
760 : // begin wrapping related part ====================
761 0 : uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
762 0 : if ( xWrappedObject.is() )
763 : {
764 : // the object was converted to OOo embedded object, the current implementation is now only a wrapper
765 0 : xWrappedObject->doVerb( nVerbID );
766 : return;
767 : }
768 : // end wrapping related part ====================
769 :
770 0 : ::osl::ResettableMutexGuard aGuard( m_aMutex );
771 0 : if ( m_bDisposed )
772 0 : throw lang::DisposedException(); // TODO
773 :
774 0 : if ( m_nObjectState == -1 )
775 : throw embed::WrongStateException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object has no persistence!\n" )),
776 0 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
777 :
778 : #ifdef WNT
779 : if ( m_pOleComponent )
780 : {
781 : sal_Int32 nOldState = m_nObjectState;
782 :
783 : // TODO/LATER detect target state here and do a notification
784 : // StateChangeNotification_Impl( sal_True, nOldState, nNewState );
785 : if ( m_nObjectState == embed::EmbedStates::LOADED )
786 : {
787 : // if the target object is in loaded state
788 : // it must be switched to running state to execute verb
789 : aGuard.clear();
790 : changeState( embed::EmbedStates::RUNNING );
791 : aGuard.reset();
792 : }
793 :
794 : try {
795 : if ( !m_pOleComponent )
796 : throw uno::RuntimeException();
797 :
798 : // ==== the STAMPIT related solution =============================
799 : m_aVerbExecutionController.StartControlExecution();
800 : // ===============================================================
801 :
802 : m_pOleComponent->ExecuteVerb( nVerbID );
803 :
804 : // ==== the STAMPIT related solution =============================
805 : sal_Bool bModifiedOnExecution = m_aVerbExecutionController.EndControlExecution_WasModified();
806 :
807 : // this workaround is implemented for STAMPIT object
808 : // if object was modified during verb execution it is saved here
809 : if ( bModifiedOnExecution && m_pOleComponent->IsDirty() )
810 : SaveObject_Impl();
811 : // ===============================================================
812 : }
813 : catch( uno::Exception& )
814 : {
815 : // ==== the STAMPIT related solution =============================
816 : m_aVerbExecutionController.EndControlExecution_WasModified();
817 : // ===============================================================
818 :
819 : aGuard.clear();
820 : StateChangeNotification_Impl( sal_False, nOldState, m_nObjectState );
821 : throw;
822 : }
823 :
824 : }
825 : else
826 : #endif
827 : {
828 0 : if ( nVerbID == -9 )
829 : {
830 : // the workaround verb to show the object in case no server is available
831 :
832 : // if it is possible, the object will be converted to OOo format
833 0 : if ( !m_bTriedConversion )
834 : {
835 0 : m_bTriedConversion = sal_True;
836 0 : if ( TryToConvertToOOo() )
837 : {
838 0 : changeState( embed::EmbedStates::UI_ACTIVE );
839 : return;
840 : }
841 : }
842 :
843 0 : if ( !m_pOwnView && m_xObjectStream.is() )
844 : {
845 : try {
846 0 : uno::Reference< io::XSeekable > xSeekable( m_xObjectStream, uno::UNO_QUERY );
847 0 : if ( xSeekable.is() )
848 0 : xSeekable->seek( 0 );
849 :
850 0 : m_pOwnView = new OwnView_Impl( m_xFactory, m_xObjectStream->getInputStream() );
851 0 : m_pOwnView->acquire();
852 : }
853 0 : catch( uno::RuntimeException& )
854 : {
855 0 : throw;
856 : }
857 0 : catch( uno::Exception& )
858 : {
859 : }
860 : }
861 :
862 0 : if ( !m_pOwnView || !m_pOwnView->Open() )
863 : {
864 : //Make a RO copy and see if the OS can find something to at
865 : //least display the content for us
866 0 : if (m_aTempDumpURL.isEmpty())
867 0 : m_aTempDumpURL = lcl_ExtractObject(m_xFactory, m_xObjectStream);
868 :
869 0 : if (!m_aTempDumpURL.isEmpty())
870 : {
871 : uno::Reference< ::com::sun::star::system::XSystemShellExecute > xSystemShellExecute(
872 0 : ::com::sun::star::system::SystemShellExecute::create(comphelper::getComponentContext(m_xFactory)) );
873 0 : xSystemShellExecute->execute(m_aTempDumpURL, ::rtl::OUString(), ::com::sun::star::system::SystemShellExecuteFlags::URIS_ONLY);
874 : }
875 : else
876 0 : throw embed::UnreachableStateException();
877 : }
878 : }
879 : else
880 : {
881 :
882 0 : throw embed::UnreachableStateException();
883 : }
884 0 : }
885 : }
886 :
887 : //----------------------------------------------
888 0 : uno::Sequence< embed::VerbDescriptor > SAL_CALL OleEmbeddedObject::getSupportedVerbs()
889 : throw ( embed::WrongStateException,
890 : uno::RuntimeException )
891 : {
892 : RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OleEmbeddedObject::getSupportedVerb" );
893 :
894 : // begin wrapping related part ====================
895 0 : uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
896 0 : if ( xWrappedObject.is() )
897 : {
898 : // the object was converted to OOo embedded object, the current implementation is now only a wrapper
899 0 : return xWrappedObject->getSupportedVerbs();
900 : }
901 : // end wrapping related part ====================
902 :
903 0 : ::osl::MutexGuard aGuard( m_aMutex );
904 0 : if ( m_bDisposed )
905 0 : throw lang::DisposedException(); // TODO
906 :
907 0 : if ( m_nObjectState == -1 )
908 : throw embed::WrongStateException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object has no persistence!\n" )),
909 0 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
910 : #ifdef WNT
911 : if ( m_pOleComponent )
912 : {
913 : // registry could be used in this case
914 : // if ( m_nObjectState == embed::EmbedStates::LOADED )
915 : // {
916 : // // the list of supported verbs can be retrieved only when object is in running state
917 : // throw embed::NeedsRunningStateException(); // TODO:
918 : // }
919 :
920 : return m_pOleComponent->GetVerbList();
921 : }
922 : else
923 : #endif
924 : {
925 0 : return uno::Sequence< embed::VerbDescriptor >();
926 0 : }
927 : }
928 :
929 : //----------------------------------------------
930 0 : void SAL_CALL OleEmbeddedObject::setClientSite(
931 : const uno::Reference< embed::XEmbeddedClient >& xClient )
932 : throw ( embed::WrongStateException,
933 : uno::RuntimeException )
934 : {
935 : // begin wrapping related part ====================
936 0 : uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
937 0 : if ( xWrappedObject.is() )
938 : {
939 : // the object was converted to OOo embedded object, the current implementation is now only a wrapper
940 0 : xWrappedObject->setClientSite( xClient );
941 0 : return;
942 : }
943 : // end wrapping related part ====================
944 :
945 0 : ::osl::MutexGuard aGuard( m_aMutex );
946 0 : if ( m_bDisposed )
947 0 : throw lang::DisposedException(); // TODO
948 :
949 0 : if ( m_xClientSite != xClient)
950 : {
951 0 : if ( m_nObjectState != embed::EmbedStates::LOADED && m_nObjectState != embed::EmbedStates::RUNNING )
952 : throw embed::WrongStateException(
953 : ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The client site can not be set currently!\n" )),
954 0 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
955 :
956 0 : m_xClientSite = xClient;
957 0 : }
958 : }
959 :
960 : //----------------------------------------------
961 0 : uno::Reference< embed::XEmbeddedClient > SAL_CALL OleEmbeddedObject::getClientSite()
962 : throw ( embed::WrongStateException,
963 : uno::RuntimeException )
964 : {
965 : // begin wrapping related part ====================
966 0 : uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
967 0 : if ( xWrappedObject.is() )
968 : {
969 : // the object was converted to OOo embedded object, the current implementation is now only a wrapper
970 0 : return xWrappedObject->getClientSite();
971 : }
972 : // end wrapping related part ====================
973 :
974 0 : ::osl::MutexGuard aGuard( m_aMutex );
975 0 : if ( m_bDisposed )
976 0 : throw lang::DisposedException(); // TODO
977 :
978 0 : if ( m_nObjectState == -1 )
979 : throw embed::WrongStateException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object has no persistence!\n" )),
980 0 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
981 :
982 0 : return m_xClientSite;
983 : }
984 :
985 : //----------------------------------------------
986 0 : void SAL_CALL OleEmbeddedObject::update()
987 : throw ( embed::WrongStateException,
988 : uno::Exception,
989 : uno::RuntimeException )
990 : {
991 : // begin wrapping related part ====================
992 0 : uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
993 0 : if ( xWrappedObject.is() )
994 : {
995 : // the object was converted to OOo embedded object, the current implementation is now only a wrapper
996 0 : xWrappedObject->update();
997 0 : return;
998 : }
999 : // end wrapping related part ====================
1000 :
1001 0 : ::osl::MutexGuard aGuard( m_aMutex );
1002 0 : if ( m_bDisposed )
1003 0 : throw lang::DisposedException(); // TODO
1004 :
1005 0 : if ( m_nObjectState == -1 )
1006 : throw embed::WrongStateException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object has no persistence!\n" )),
1007 0 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1008 :
1009 0 : if ( m_nUpdateMode == embed::EmbedUpdateModes::EXPLICIT_UPDATE )
1010 : {
1011 : // TODO: update view representation
1012 : }
1013 : else
1014 : {
1015 : // the object must be up to date
1016 : OSL_ENSURE( m_nUpdateMode == embed::EmbedUpdateModes::ALWAYS_UPDATE, "Unknown update mode!\n" );
1017 0 : }
1018 : }
1019 :
1020 : //----------------------------------------------
1021 0 : void SAL_CALL OleEmbeddedObject::setUpdateMode( sal_Int32 nMode )
1022 : throw ( embed::WrongStateException,
1023 : uno::RuntimeException )
1024 : {
1025 : // begin wrapping related part ====================
1026 0 : uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
1027 0 : if ( xWrappedObject.is() )
1028 : {
1029 : // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1030 0 : xWrappedObject->setUpdateMode( nMode );
1031 0 : return;
1032 : }
1033 : // end wrapping related part ====================
1034 :
1035 0 : ::osl::MutexGuard aGuard( m_aMutex );
1036 0 : if ( m_bDisposed )
1037 0 : throw lang::DisposedException(); // TODO
1038 :
1039 0 : if ( m_nObjectState == -1 )
1040 : throw embed::WrongStateException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object has no persistence!\n" )),
1041 0 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1042 :
1043 : OSL_ENSURE( nMode == embed::EmbedUpdateModes::ALWAYS_UPDATE
1044 : || nMode == embed::EmbedUpdateModes::EXPLICIT_UPDATE,
1045 : "Unknown update mode!\n" );
1046 0 : m_nUpdateMode = nMode;
1047 : }
1048 :
1049 : //----------------------------------------------
1050 0 : sal_Int64 SAL_CALL OleEmbeddedObject::getStatus( sal_Int64
1051 : nAspect
1052 : )
1053 : throw ( embed::WrongStateException,
1054 : uno::RuntimeException )
1055 : {
1056 : // begin wrapping related part ====================
1057 0 : uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
1058 0 : if ( xWrappedObject.is() )
1059 : {
1060 : // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1061 0 : return xWrappedObject->getStatus( nAspect );
1062 : }
1063 : // end wrapping related part ====================
1064 :
1065 0 : ::osl::MutexGuard aGuard( m_aMutex );
1066 0 : if ( m_bDisposed )
1067 0 : throw lang::DisposedException(); // TODO
1068 :
1069 0 : if ( m_nObjectState == -1 )
1070 : throw embed::WrongStateException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object must be in running state!\n" )),
1071 0 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1072 :
1073 0 : sal_Int64 nResult = 0;
1074 :
1075 : #ifdef WNT
1076 : if ( m_bGotStatus && m_nStatusAspect == nAspect )
1077 : nResult = m_nStatus;
1078 : else if ( m_pOleComponent )
1079 : {
1080 :
1081 : m_nStatus = m_pOleComponent->GetMiscStatus( nAspect );
1082 : m_nStatusAspect = nAspect;
1083 : m_bGotStatus = sal_True;
1084 : nResult = m_nStatus;
1085 : }
1086 : #endif
1087 :
1088 : // this implementation needs size to be provided after object loading/creating to work in optimal way
1089 0 : return ( nResult | embed::EmbedMisc::EMBED_NEEDSSIZEONLOAD );
1090 : }
1091 :
1092 : //----------------------------------------------
1093 0 : void SAL_CALL OleEmbeddedObject::setContainerName( const ::rtl::OUString& sName )
1094 : throw ( uno::RuntimeException )
1095 : {
1096 : // begin wrapping related part ====================
1097 0 : uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
1098 0 : if ( xWrappedObject.is() )
1099 : {
1100 : // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1101 0 : xWrappedObject->setContainerName( sName );
1102 0 : return;
1103 : }
1104 : // end wrapping related part ====================
1105 :
1106 0 : ::osl::MutexGuard aGuard( m_aMutex );
1107 0 : if ( m_bDisposed )
1108 0 : throw lang::DisposedException(); // TODO
1109 :
1110 0 : m_aContainerName = sName;
1111 : }
1112 :
1113 :
1114 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|